diff --git a/apps/plugins/grayscale.c b/apps/plugins/grayscale.c index 196545c0e7..e543f15427 100644 --- a/apps/plugins/grayscale.c +++ b/apps/plugins/grayscale.c @@ -44,7 +44,7 @@ void cleanup(void *parameter) { (void)parameter; - gray_release_buffer(); /* switch off overlay and deinitialize */ + gray_release(); /* switch off overlay and deinitialize */ /* restore normal backlight setting */ rb->backlight_set_timeout(rb->global_settings->backlight_timeout); } @@ -55,7 +55,7 @@ int main(void) int shades, time; int x, y, i; int button, scroll_amount; - bool black_border; + bool black_border = false; static const unsigned char rockbox[] = { /* ........................................... @@ -138,73 +138,74 @@ int main(void) /* get the remainder of the plugin buffer */ gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); - /* initialize the grayscale buffer: + /* initialize the greyscale buffer: * 112 pixels wide, 7 rows (56 pixels) high, (try to) reserve - * 32 bitplanes for 33 shades of gray. (uses 25268 bytes)*/ - shades = gray_init_buffer(gbuf, gbuf_size, 112, 7, 32, NULL) + 1; + * 32 bitplanes for 33 shades of grey. */ + shades = gray_init(rb, gbuf, gbuf_size, true, 112, 7, 32, NULL) + 1; - /* place grayscale overlay 1 row down */ - gray_position_display(0, 1); + /* place greyscale overlay 1 row down */ + gray_set_position(0, 1); rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades); rb->lcd_puts(0, 0, pbuf); rb->lcd_update(); - gray_show_display(true); /* switch on grayscale overlay */ + gray_show(true); /* switch on greyscale overlay */ time = *rb->current_tick; /* start time measurement */ - gray_set_foreground(150); - gray_fillrect(0, 0, 112, 56); /* fill everything with gray 150 */ + gray_set_background(150); + gray_clear_display(); /* fill everything with grey 150 */ - /* draw a dark gray line star background */ + /* draw a dark grey line star background */ gray_set_foreground(80); - for (y = 0; y < 56; y += 8) /* horizontal part */ + for (y = 0; y < 56; y += 8) /* horizontal part */ { - gray_drawline(0, y, 111, 55 - y); /* gray lines */ + gray_drawline(0, y, 111, 55 - y); /* grey lines */ } - for (x = 10; x < 112; x += 10) /* vertical part */ + for (x = 10; x < 112; x += 10) /* vertical part */ { - gray_drawline(x, 0, 111 - x, 55); /* gray lines */ + gray_drawline(x, 0, 111 - x, 55); /* grey lines */ } gray_set_foreground(0); gray_drawrect(0, 0, 112, 56); /* black border */ - /* draw gray tones */ + /* draw grey tones */ for (i = 0; i < 86; i++) { x = 13 + i; gray_set_foreground(3 * i); - gray_verline(x, 6, 49); /* vertical lines */ + gray_vline(x, 6, 49); /* vertical lines */ } - gray_set_drawmode(GRAY_DRAW_INVERSE); + gray_set_drawmode(DRMODE_COMPLEMENT); gray_fillrect(13, 29, 86, 21); /* invert rectangle (lower half) */ gray_drawline(13, 27, 98, 27); /* invert a line */ /* show bitmaps (1 bit and 8 bit) */ - gray_set_drawinfo(GRAY_DRAW_SOLID, 255, 100); - gray_drawbitmap(rockbox, 14, 13, 43, 7, 43); /* opaque */ - gray_set_drawinfo(GRAY_DRAW_FG, 0, -1); - gray_drawbitmap(showing, 58, 13, 39, 7, 39); /* transparent */ + gray_set_drawinfo(DRMODE_SOLID, 255, 100); + gray_mono_bitmap(rockbox, 14, 13, 43, 7); /* opaque */ + gray_set_drawinfo(DRMODE_FG, 0, 100); + gray_mono_bitmap(showing, 58, 13, 39, 7); /* transparent */ + gray_gray_bitmap(grayscale_gray, 28, 35, 55, 7); - gray_drawgraymap(grayscale_gray, 28, 35, 55, 7, 55); + gray_update(); time = *rb->current_tick - time; /* end time measurement */ rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d, %d.%02ds", shades, time / 100, time % 100); rb->lcd_puts(0, 0, pbuf); - gray_deferred_update(); /* schedule an lcd_update() */ + gray_deferred_lcd_update(); /* schedule an lcd_update() */ /* drawing is now finished, play around with scrolling * until you press OFF or connect USB */ + gray_set_background(255); while (true) { scroll_amount = 1; - black_border = false; button = rb->button_get(true); @@ -213,31 +214,49 @@ int main(void) return PLUGIN_USB_CONNECTED; if (button & GRAYSCALE_SHIFT) - black_border = true; - + { + if (!black_border) + { + gray_set_background(0); + black_border = true; + } + } + else + { + if (black_border) + { + gray_set_background(255); + black_border = false; + } + } + if (button & BUTTON_REPEAT) scroll_amount = 4; - switch(button & ~(GRAYSCALE_SHIFT | BUTTON_REPEAT)) + switch (button & ~(GRAYSCALE_SHIFT | BUTTON_REPEAT)) { case BUTTON_LEFT: - gray_scroll_left(scroll_amount, black_border); /* scroll left */ + gray_scroll_left(scroll_amount); /* scroll left */ + gray_update(); break; case BUTTON_RIGHT: - gray_scroll_right(scroll_amount, black_border); /* scroll right */ + gray_scroll_right(scroll_amount); /* scroll right */ + gray_update(); break; case BUTTON_UP: - gray_scroll_up(scroll_amount, black_border); /* scroll up */ + gray_scroll_up(scroll_amount); /* scroll up */ + gray_update(); break; case BUTTON_DOWN: - gray_scroll_down(scroll_amount, black_border); /* scroll down */ + gray_scroll_down(scroll_amount); /* scroll down */ + gray_update(); break; case BUTTON_OFF: @@ -260,9 +279,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb = api; // copy to global api pointer (void)parameter; - /* This plugin uses the grayscale framework, so initialize */ - gray_init(api); - return main(); } diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c index 7ca59b29cd..5060996639 100644 --- a/apps/plugins/jpeg.c +++ b/apps/plugins/jpeg.c @@ -1523,7 +1523,7 @@ void cleanup(void *parameter) { (void)parameter; - gray_show_display(false); + gray_show(false); } /* interactively scroll around the image */ @@ -1548,13 +1548,12 @@ int scroll_bmp(struct t_disp* pdisp) move = MIN(10, pdisp->x); if (move > 0) { - gray_scroll_right(move, false); /* scroll right */ + gray_ub_scroll_right(move); /* scroll right */ pdisp->x -= move; - gray_drawgraymap( - pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, - 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), // x, y - move, MIN(LCD_HEIGHT, pdisp->height), // w, h - pdisp->stride); + gray_ub_gray_bitmap_part( + pdisp->bitmap, pdisp->x, pdisp->y, pdisp->stride, + 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ + move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ } break; @@ -1563,13 +1562,13 @@ int scroll_bmp(struct t_disp* pdisp) move = MIN(10, pdisp->width - pdisp->x - LCD_WIDTH); if (move > 0) { - gray_scroll_left(move, false); /* scroll left */ + gray_ub_scroll_left(move); /* scroll left */ pdisp->x += move; - gray_drawgraymap( - pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x + LCD_WIDTH - move, + gray_ub_gray_bitmap_part( + pdisp->bitmap, pdisp->x + LCD_WIDTH - move, + pdisp->y, pdisp->stride, LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ - move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ - pdisp->stride); + move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ } break; @@ -1578,16 +1577,12 @@ int scroll_bmp(struct t_disp* pdisp) move = MIN(8, pdisp->y); if (move > 0) { - if (move == 8) - gray_scroll_down8(false); /* scroll down by 8 pixel */ - else - gray_scroll_down(move, false); /* scroll down 1..7 pixel */ + gray_ub_scroll_down(move); /* scroll down */ pdisp->y -= move; - gray_drawgraymap( - pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, - MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ - MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ - pdisp->stride); + gray_ub_gray_bitmap_part( + pdisp->bitmap, pdisp->x, pdisp->y, pdisp->stride, + MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ + MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ } break; @@ -1596,16 +1591,13 @@ int scroll_bmp(struct t_disp* pdisp) move = MIN(8, pdisp->height - pdisp->y - LCD_HEIGHT); if (move > 0) { - if (move == 8) - gray_scroll_up8(false); /* scroll up by 8 pixel */ - else - gray_scroll_up(move, false); /* scroll up 1..7 pixel */ + gray_ub_scroll_up(move); /* scroll up */ pdisp->y += move; - gray_drawgraymap( - pdisp->bitmap + (pdisp->y + LCD_HEIGHT - move) * pdisp->stride + pdisp->x, + gray_ub_gray_bitmap_part( + pdisp->bitmap, pdisp->x, + pdisp->y + LCD_HEIGHT - move, pdisp->stride, MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ - MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ - pdisp->stride); + MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ } break; @@ -1806,7 +1798,7 @@ int main(char* filename) int fd; int filesize; int grayscales; - int graysize; // helper + long graysize; // helper unsigned char* buf_jpeg; /* compressed JPEG image */ static struct jpeg jpg; /* too large for stack */ int status; @@ -1830,7 +1822,7 @@ int main(char* filename) /* initialize the grayscale buffer: * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve * 32 bitplanes for 33 shades of gray. (uses 28856 bytes)*/ - grayscales = gray_init_buffer(buf, buf_size, 112, 8, 32, &graysize) + 1; + grayscales = gray_init(rb, buf, buf_size, false, 112, 8, 32, &graysize) + 1; buf += graysize; buf_size -= graysize; if (grayscales < 33 || buf_size <= 0) @@ -1907,16 +1899,15 @@ int main(char* filename) rb->lcd_puts(0, 3, print); rb->lcd_update(); - gray_clear_display(); - gray_drawgraymap( - p_disp->bitmap + p_disp->y * p_disp->stride + p_disp->x, + gray_ub_clear_display(); + gray_ub_gray_bitmap_part( + p_disp->bitmap, p_disp->x, p_disp->y, p_disp->stride, MAX(0, (LCD_WIDTH - p_disp->width) / 2), MAX(0, (LCD_HEIGHT - p_disp->height) / 2), MIN(LCD_WIDTH, p_disp->width), - MIN(LCD_HEIGHT, p_disp->height), - p_disp->stride); + MIN(LCD_HEIGHT, p_disp->height)); - gray_show_display(true); /* switch on grayscale overlay */ + gray_show(true); /* switch on grayscale overlay */ /* drawing is now finished, play around with scrolling * until you press OFF or connect USB @@ -1952,12 +1943,12 @@ int main(char* filename) break; } - gray_show_display(false); /* switch off overlay */ + gray_show(false); /* switch off overlay */ } while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED); - gray_release_buffer(); /* deinitialize */ + gray_release(); /* deinitialize */ return status; } @@ -1973,9 +1964,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb = api; /* copy to global api pointer */ - /* This plugin uses the grayscale framework, so initialize */ - gray_init(api); - return main((char*)parameter); } diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 00cc6d82c4..4b625cc5f8 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -1,35 +1,10 @@ configfile.c highscore.c #if (CONFIG_LCD == LCD_SSD1815) && !defined(SIMULATOR) -gray_black_display.c -gray_blockfuncs.c -gray_clear_display.c gray_core.c -gray_deferred_update.c -gray_drawbitmap.c -gray_drawgraymap.c -gray_drawline.c -gray_drawpixel.c -gray_drawrect.c -gray_fillrect.c -gray_getstringsize.c -gray_horline.c -gray_pixelfuncs.c -gray_position_display.c -gray_putsxy.c -gray_screendump.c -gray_scroll_down.c -gray_scroll_down8.c -gray_scroll_left.c -gray_scroll_right.c -gray_scroll_up.c -gray_scroll_up8.c -gray_set_background.c -gray_set_drawinfo.c -gray_set_drawmode.c -gray_set_foreground.c -gray_setfont.c -gray_verline.c +gray_draw.c +gray_parm.c +gray_scroll.c #endif #ifdef HAVE_LCD_BITMAP xlcd.c diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h index 52d6f6c0df..8abf7bc16d 100644 --- a/apps/plugins/lib/gray.h +++ b/apps/plugins/lib/gray.h @@ -7,12 +7,12 @@ * \/ \/ \/ \/ \/ * $Id$ * -* Grayscale framework +* Greyscale framework * -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. +* This is a generic framework to use greyscale display within Rockbox +* plugins. It does not work for the player. * -* Copyright (C) 2004 Jens Arnold +* Copyright (C) 2004-2005 Jens Arnold * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -30,401 +30,94 @@ #ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -/*=========================================================================== - Public functions and definitions, to be used within plugins - ============================================================================ - */ +#define GRAY_MAX_LEVEL 255 /* The real value is variable, so normalise */ +#define GRAY_BLACK 0 +#define GRAY_WHITE GRAY_MAX_LEVEL -/*--------------------------------------------------------------------------- - Initialize the framework - ---------------------------------------------------------------------------- - every framework needs such a function, and it has to be called as the very - first one - */ -void gray_init(struct plugin_api* newrb); +/* Library initialisation and release */ +int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, + bool buffered, int width, int bheight, int depth, long *buf_taken); +void gray_release(void); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - General functions - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -/*--------------------------------------------------------------------------- - Prepare the grayscale display buffer - ---------------------------------------------------------------------------- - arguments: - gbuf = pointer to the memory area to use (e.g. plugin buffer) - gbuf_size = max usable size of the buffer - width = width in pixels (1..112) - bheight = height in 8-pixel units (1..8) - depth = desired number of shades - 1 (1..32) - - result: - = depth if there was enough memory - < depth if there wasn't enough memory. The number of displayable - shades is smaller than desired, but it still works - = 0 if there wasn't even enough memory for 1 bitplane (black & white) - - You can request any depth from 1 to 32, not just powers of 2. The routine - performs "graceful degradation" if the memory is not sufficient for the - desired depth. As long as there is at least enough memory for 1 bitplane, - it creates as many bitplanes as fit into memory, although 1 bitplane will - only deliver black & white display. - - If you need info about the memory taken by the grayscale buffer, supply an - int* as the last parameter. This int will then contain the number of bytes - used. The total memory needed can be calculated as follows: - total_mem = - sizeof(_tGraybuf) (= 64 bytes currently) - + sizeof(long) (= 4 bytes) - + (width * bheight + sizeof(long)) * depth - + 0..3 (longword alignment of grayscale display buffer) - */ -int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, - int bheight, int depth, int *buf_taken); - -/*--------------------------------------------------------------------------- - Release the grayscale display buffer - ---------------------------------------------------------------------------- - Switches the grayscale overlay off at first if it is still running, - then sets the pointer to NULL. - DO CALL either this function or at least gray_show_display(false) - before you exit, otherwise nasty things may happen. - */ -void gray_release_buffer(void); - -/*--------------------------------------------------------------------------- - Switch the grayscale overlay on or off - ---------------------------------------------------------------------------- - enable = true: the grayscale overlay is switched on if initialized - = false: the grayscale overlay is switched off and the regular lcd - content is restored - - DO NOT call lcd_update() or any other api function that directly accesses - the lcd while the grayscale overlay is running! If you need to do - lcd_update() to update something outside the grayscale overlay area, use - gray_deferred_update() instead. - - Other functions to avoid are: - lcd_blit() (obviously), lcd_update_rect(), lcd_set_contrast(), - lcd_set_invert_display(), lcd_set_flip(), lcd_roll() - - The grayscale display consumes ~50 % CPU power (for a full screen overlay, - less if the overlay is smaller) when switched on. You can switch the overlay - on and off as many times as you want. - */ -void gray_show_display(bool enable); - -/*--------------------------------------------------------------------------- - Set position of the top left corner of the grayscale overlay - ---------------------------------------------------------------------------- - x = left margin in pixels - by = top margin in 8-pixel units - - You may set this in a way that the overlay spills across the right or - bottom display border. In this case it will simply be clipped by the - LCD controller. You can even set negative values, this will clip at the - left or top border. I did not test it, but the limits may be +127 / -128 - - If you use this while the grayscale overlay is running, the now-freed area - will be restored. - */ -void gray_position_display(int x, int by); - -/*--------------------------------------------------------------------------- - Set the draw mode for subsequent drawing operations - ---------------------------------------------------------------------------- - drawmode = - GRAY_DRAW_INVERSE: Foreground pixels are inverted, background pixels are - left untouched - GRAY_DRAW_FG: Only foreground pixels are drawn - GRAY_DRAW_BG: Only background pixels are drawn - GRAY_DRAW_SOLID: Foreground and background pixels are drawn - - Default after initialization: GRAY_DRAW_SOLID - */ -void gray_set_drawmode(int drawmode); - -/*--------------------------------------------------------------------------- - Draw modes, see above - ---------------------------------------------------------------------------- - */ -#define GRAY_DRAW_INVERSE 0 -#define GRAY_DRAW_FG 1 -#define GRAY_DRAW_BG 2 -#define GRAY_DRAW_SOLID 3 - -/*--------------------------------------------------------------------------- - Set the foreground shade for subsequent drawing operations - ---------------------------------------------------------------------------- - brightness = 0 (black) .. 255 (white) - - Default after initialization: 0 - */ -void gray_set_foreground(int brightness); - -/*--------------------------------------------------------------------------- - Set the background shade for subsequent drawing operations - ---------------------------------------------------------------------------- - brightness = 0 (black) .. 255 (white) - - Default after initialization: 255 - */ -void gray_set_background(int brightness); - -/*--------------------------------------------------------------------------- - Set draw mode, foreground and background shades at once - ---------------------------------------------------------------------------- - If you hand it -1 (or in fact any other out-of-bounds value) for a - parameter, that particular setting won't be changed - - Default after initialization: GRAY_DRAW_SOLID, 0, 255 - */ -void gray_set_drawinfo(int drawmode, int fg_brightness, int bg_brightness); - -/*--------------------------------------------------------------------------- - Save the current display content (b&w and grayscale overlay) to an 8-bit - BMP file in the root directory - ---------------------------------------------------------------------------- - * - * This one is rather slow if used with larger bit depths, but it's intended - * primary use is for documenting the grayscale plugins. A much faster version - * would be possible, but would take more than twice the RAM - */ +/* Special functions */ +void gray_show(bool enable); +void gray_deferred_lcd_update(void); void gray_screendump(void); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Functions affecting the whole display - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ +/* Update functions */ +void gray_update(void); +void gray_update_rect(int x, int y, int width, int height); -/*--------------------------------------------------------------------------- - Clear the grayscale display (sets all pixels to white) - ---------------------------------------------------------------------------- - */ +/* Parameter handling */ +void gray_set_position(int x, int by); +void gray_set_drawmode(int mode); +int gray_get_drawmode(void); +void gray_set_foreground(int brightness); +int gray_get_foreground(void); +void gray_set_background(int brightness); +int gray_get_background(void); +void gray_set_drawinfo(int mode, int fg_brightness, int bg_brightness); +void gray_setfont(int newfont); +int gray_getstringsize(const unsigned char *str, int *w, int *h); + +/* Whole display */ void gray_clear_display(void); +void gray_ub_clear_display(void); -/*--------------------------------------------------------------------------- - Set the grayscale display to all black - ---------------------------------------------------------------------------- - */ -void gray_black_display(void); - -/*--------------------------------------------------------------------------- - Do an lcd_update() to show changes done by rb->lcd_xxx() functions (in areas - of the screen not covered by the grayscale overlay). - ---------------------------------------------------------------------------- - If the grayscale overlay is running, the update will be done in the next - call of the interrupt routine, otherwise it will be performed right away. - See also comment for the gray_show_display() function. - */ -void gray_deferred_update(void); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Scrolling functions - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer left by pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the right are black - or white - - Scrolling left/right by an even pixel count is almost twice as fast as - scrolling by an odd pixel count. - */ -void gray_scroll_left(int count, bool black_border); - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer right by pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the left are black - or white - - Scrolling left/right by an even pixel count is almost twice as fast as - scrolling by an odd pixel count. - */ -void gray_scroll_right(int count, bool black_border); - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer up by 8 pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the bottom are black - or white - - Scrolling up/down by 8 pixels is very fast. - */ -void gray_scroll_up8(bool black_border); - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer down by 8 pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the top are black - or white - - Scrolling up/down by 8 pixels is very fast. - */ -void gray_scroll_down8(bool black_border); - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer up by pixels (<= 7) - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the bottom are black - or white - - Scrolling up/down pixel-wise is significantly slower than scrolling - left/right or scrolling up/down byte-wise because it involves bit - shifting. That's why it is asm optimized. - */ -void gray_scroll_up(int count, bool black_border); - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer down by pixels (<= 7) - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the top are black - or white - - Scrolling up/down pixel-wise is significantly slower than scrolling - left/right or scrolling up/down byte-wise because it involves bit - shifting. That's why it is asm optimized. - */ -void gray_scroll_down(int count, bool black_border); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Pixel and line functions - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -/*--------------------------------------------------------------------------- - Set a pixel with the current drawinfo - ---------------------------------------------------------------------------- - If the drawmode is GRAY_DRAW_INVERSE, the pixel is inverted - GRAY_DRAW_FG and GRAY_DRAW_SOLID draw the pixel in the foreground shade - GRAY_DRAW_BG draws the pixel in the background shade - */ +/* Pixel */ void gray_drawpixel(int x, int y); -/*--------------------------------------------------------------------------- - Draw a line from (x1, y1) to (x2, y2) with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - */ +/* Lines */ void gray_drawline(int x1, int y1, int x2, int y2); - -/*--------------------------------------------------------------------------- - Draw a horizontal line from (x1, y) to (x2, y) with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - */ -void gray_horline(int x1, int x2, int y); - -/*--------------------------------------------------------------------------- - Draw a vertical line from (x, y1) to (x, y2) with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - This one uses the block drawing optimization, so it is rather fast. - */ -void gray_verline(int x, int y1, int y2); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Rectangle functions - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -/*--------------------------------------------------------------------------- - Draw a (hollow) rectangle with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - */ +void gray_hline(int x1, int x2, int y); +void gray_vline(int x, int y1, int y2); void gray_drawrect(int x, int y, int nx, int ny); -/*--------------------------------------------------------------------------- - Draw a filled rectangle with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - This one uses the block drawing optimization, so it is rather fast. - */ +/* Filled primitives */ void gray_fillrect(int x, int y, int nx, int ny); +void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Bitmap functions - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ +/* Bitmaps */ +void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); +void gray_mono_bitmap(const unsigned char *src, int x, int y, int width, + int height); +void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); +void gray_gray_bitmap(const unsigned char *src, int x, int y, int width, + int height); +void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height); +void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width, + int height); -/*--------------------------------------------------------------------------- - Copy a grayscale bitmap into the display - ---------------------------------------------------------------------------- - A grayscale bitmap contains one byte for every pixel that defines the - brightness of the pixel (0..255). Bytes are read in row-major order. - The parameter is useful if you want to show only a part of a - bitmap. It should always be set to the "row length" of the bitmap, so - for displaying the whole bitmap, nx == stride. - - This is the only drawing function NOT using the drawinfo. - */ -void gray_drawgraymap(const unsigned char *src, int x, int y, int nx, int ny, - int stride); - -/*--------------------------------------------------------------------------- - Display a bitmap with the current drawinfo - ---------------------------------------------------------------------------- - The drawmode is used as described for gray_set_drawmode() - - This (now) uses the same bitmap format as the core b&w graphics routines, - so you can use bmp2rb to generate bitmaps for use with this function as - well. - - A bitmap contains one bit for every pixel that defines if that pixel is - foreground (1) or background (0). Bits within a byte are arranged - vertically, LSB at top. - The bytes are stored in row-major order, with byte 0 being top left, - byte 1 2nd from left etc. The first row of bytes defines pixel rows - 0..7, the second row defines pixel row 8..15 etc. - - The parameter is useful if you want to show only a part of a - bitmap. It should always be set to the "row length" of the bitmap. - */ -void gray_drawbitmap(const unsigned char *src, int x, int y, int nx, int ny, - int stride); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - Font support - ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - */ - -/*--------------------------------------------------------------------------- - Set font for the font routines - ---------------------------------------------------------------------------- - newfont can be FONT_SYSFIXED or FONT_UI the same way as with the Rockbox - core routines - - Default after initialization: FONT_SYSFIXED - */ -void gray_setfont(int newfont); - -/*--------------------------------------------------------------------------- - Calculate width and height of the given text in pixels when rendered with - the currently selected font. - ---------------------------------------------------------------------------- - This works exactly the same way as the core lcd_getstringsize(), only that - it uses the selected font for grayscale. - */ -int gray_getstringsize(const unsigned char *str, int *w, int *h); - -/*--------------------------------------------------------------------------- - Display text starting at (x, y) with the current font and drawinfo - ---------------------------------------------------------------------------- - The drawmode is used as described for gray_set_drawmode() - */ +/* Text */ +void gray_putsxyofs(int x, int y, int ofs, const unsigned char *str); void gray_putsxy(int x, int y, const unsigned char *str); -/*=========================================================================== - Private functions and definitions, for use within the grayscale core only - ============================================================================ - */ +/* Scrolling */ +void gray_scroll_left(int count); +void gray_scroll_right(int count); +void gray_scroll_up(int count); +void gray_scroll_down(int count); +void gray_ub_scroll_left(int count); +void gray_ub_scroll_right(int count); +void gray_ub_scroll_up(int count); +void gray_ub_scroll_down(int count); + +/*** Internal stuff ***/ + +#if LCD_DEPTH == 1 +#define _PBLOCK_EXP 3 +#elif LCD_DEPTH == 2 +#define _PBLOCK_EXP 2 +#endif +#define _PBLOCK (1 << _PBLOCK_EXP) +#define _MAX_DEPTH (32 / LCD_DEPTH) +#define _LEVEL_FAC ((1 << LCD_DEPTH) - 1) /* flag definitions */ -#define _GRAY_RUNNING 0x0001 /* grayscale overlay is running */ +#define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */ #define _GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */ /* unsigned 16 bit multiplication (a single instruction on the SH) */ @@ -432,36 +125,33 @@ void gray_putsxy(int x, int y, const unsigned char *str); (((unsigned short) (a)) * ((unsigned short) (b)))) /* The grayscale buffer management structure */ -typedef struct +struct _gray_info { int x; int by; /* 8-pixel units */ int width; int height; int bheight; /* 8-pixel units */ - int plane_size; int depth; /* number_of_bitplanes = (number_of_grayscales - 1) */ int cur_plane; /* for the timer isr */ - unsigned long randmask; /* mask for random value in _writepixel() */ - unsigned long flags; /* various flags, see #defines */ - unsigned long *bitpattern; /* pointer to start of pattern table */ - unsigned char *data; /* pointer to start of bitplane data */ - unsigned long fg_pattern; /* current foreground pattern */ - unsigned long bg_pattern; /* current background pattern */ int drawmode; /* current draw mode */ - struct font *curfont; /* current selected font */ -} _tGraybuf; + int fg_brightness; /* current foreground brightness */ + int bg_brightness; /* current background brightness */ + long plane_size; + unsigned long flags; /* various flags, see #defines */ + unsigned long randmask; /* mask for random value in _writepixel() */ + unsigned long *bitpattern; /* start of pattern table */ + unsigned char *plane_data; /* start of bitplane data */ + unsigned char *cur_buffer; /* start of current chunky pixel buffer */ + unsigned char *back_buffer;/* start of chunky pixel back buffer */ + int curfont; /* current selected font */ +}; /* Global variables */ extern struct plugin_api *_gray_rb; -extern _tGraybuf *_graybuf; +extern struct _gray_info _gray_info; extern short _gray_random_buffer; -/* Global function pointers */ -extern void (* const _gray_pixelfuncs[4])(int x, int y, unsigned long pattern); -extern void (* const _gray_blockfuncs[4])(unsigned char *address, unsigned mask, - unsigned bits); - #endif /* HAVE_LCD_BITMAP */ -#endif /* SIMULATOR */ +#endif /* !SIMULATOR */ #endif /* __GRAY_H__ */ diff --git a/apps/plugins/lib/gray_black_display.c b/apps/plugins/lib/gray_black_display.c deleted file mode 100644 index 573060eb62..0000000000 --- a/apps/plugins/lib/gray_black_display.c +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_black_display() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set the grayscale display to all black - ---------------------------------------------------------------------------- - */ -void gray_black_display(void) -{ - _gray_rb->memset(_graybuf->data, 0xFF, MULU16(_graybuf->depth, - _graybuf->plane_size)); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_blockfuncs.c b/apps/plugins/lib/gray_blockfuncs.c deleted file mode 100644 index 85af0014e1..0000000000 --- a/apps/plugins/lib/gray_blockfuncs.c +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* Low level block drawing functions -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/* Prototypes */ -static void _writeblock(unsigned char *address, unsigned mask, unsigned bits); -static void _invertblock(unsigned char *address, unsigned mask, unsigned bits); -static void _writeblockfg(unsigned char *address, unsigned mask, unsigned bits); -static void _writeblockbg(unsigned char *address, unsigned mask, unsigned bits); - -/* Block function pointer array */ -void (* const _gray_blockfuncs[4])(unsigned char *address, unsigned mask, - unsigned bits) = { - _invertblock, _writeblockfg, _writeblockbg, _writeblock -}; - -/* Write an 8-pixel block, defined by foreground and background pattern. - * Address is the byte in the first bitplane, mask determines which pixels to - * set, and bits determines if the pixel is foreground or background */ -static void _writeblock(unsigned char *address, unsigned mask, unsigned bits) -{ - unsigned long pat_stack[8]; - register unsigned char *end_addr; - register unsigned long *pat_ptr = &pat_stack[8]; - - /* precalculate the bit patterns with random shifts (same RNG as _writepixel, - * see there for an explanation) for all 8 pixels and put them on an - * extra stack */ - asm ( - "mov #8,r3 \n" /* loop count in r3: 8 pixels */ - "mov %6,r2 \n" /* copy mask */ - - ".wb_loop: \n" /** load pattern for pixel **/ - "shlr r2 \n" /* shift out lsb of mask */ - "bf .wb_skip \n" /* skip this pixel */ - - "mov %2,r4 \n" /* load foreground pattern */ - "shlr %7 \n" /* shift out lsb of bits */ - "bt .wb_fg \n" /* foreground? -> skip next insn */ - "mov %3,r4 \n" /* load background pattern */ - ".wb_fg: \n" - - "mov #75,r0 \n" - "mulu r0,%0 \n" /* multiply by 75 */ - "sts macl,%0 \n" - "add #74,%0 \n" /* add another 74 */ - /* Since the lower bits are not very random: */ - "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */ - "and %5,r1 \n" /* mask out unneeded bits */ - - "cmp/hs %4,r1 \n" /* random >= depth ? */ - "bf .wb_ntrim \n" - "sub %4,r1 \n" /* yes: random -= depth; */ - ".wb_ntrim: \n" - - "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ - "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ - "mov r1,r5 \n" - - "mov %4,r5 \n" - "sub r1,r5 \n" /* r5 = depth - r1 */ - "mov.l .lshrsi3,r1 \n" - "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ - "mov r0,r1 \n" /* store previous result in r1 */ - - "bra .wb_store \n" - "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ - - ".wb_skip: \n" - "shlr %7 \n" /* shift out lsb of bits to keep in sync */ - "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */ - - ".wb_store: \n" - "mov.l r0,@-%1 \n" /* push on pattern stack */ - - "add #-1,r3 \n" /* decrease loop count */ - "cmp/pl r3 \n" /* loop count > 0? */ - "bt .wb_loop \n" /* yes: loop */ - : /* outputs */ - /* %0, in & out */ "+r"(_gray_random_buffer), - /* %1, in & out */ "+r"(pat_ptr) - : /* inputs */ - /* %2 */ "r"(_graybuf->fg_pattern), - /* %3 */ "r"(_graybuf->bg_pattern), - /* %4 */ "r"(_graybuf->depth), - /* %5 */ "r"(_graybuf->randmask), - /* %6 */ "r"(mask), - /* %7 */ "r"(bits) - : /* clobbers */ - "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr" - ); - - end_addr = address + MULU16(_graybuf->depth, _graybuf->plane_size); - - /* set the bits for all 8 pixels in all bytes according to the - * precalculated patterns on the pattern stack */ - asm volatile ( - "mov.l @%3+,r1 \n" /* pop all 8 patterns */ - "mov.l @%3+,r2 \n" - "mov.l @%3+,r3 \n" - "mov.l @%3+,r8 \n" - "mov.l @%3+,r9 \n" - "mov.l @%3+,r10 \n" - "mov.l @%3+,r11 \n" - "mov.l @%3+,r12 \n" - - "not %4,%4 \n" /* "set" mask -> "keep" mask */ - "extu.b %4,%4 \n" /* mask out high bits */ - "tst %4,%4 \n" /* nothing to keep? */ - "bt .wb_sloop \n" /* yes: jump to short loop */ - - ".wb_floop: \n" /** full loop (there are bits to keep)**/ - "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ - "rotcl r0 \n" /* rotate t bit into r0 */ - "shlr r2 \n" - "rotcl r0 \n" - "shlr r3 \n" - "rotcl r0 \n" - "shlr r8 \n" - "rotcl r0 \n" - "shlr r9 \n" - "rotcl r0 \n" - "shlr r10 \n" - "rotcl r0 \n" - "shlr r11 \n" - "rotcl r0 \n" - "shlr r12 \n" - "mov.b @%0,%3 \n" /* read old value */ - "rotcl r0 \n" - "and %4,%3 \n" /* mask out unneeded bits */ - "or r0,%3 \n" /* set new bits */ - "mov.b %3,@%0 \n" /* store value to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ - "bt .wb_floop \n" /* no: loop */ - - "bra .wb_end \n" - "nop \n" - - ".wb_sloop: \n" /** short loop (nothing to keep) **/ - "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ - "rotcl r0 \n" /* rotate t bit into r0 */ - "shlr r2 \n" - "rotcl r0 \n" - "shlr r3 \n" - "rotcl r0 \n" - "shlr r8 \n" - "rotcl r0 \n" - "shlr r9 \n" - "rotcl r0 \n" - "shlr r10 \n" - "rotcl r0 \n" - "shlr r11 \n" - "rotcl r0 \n" - "shlr r12 \n" - "rotcl r0 \n" - "mov.b r0,@%0 \n" /* store byte to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ - "bt .wb_sloop \n" /* no: loop */ - - ".wb_end: \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(address), - /* %1 */ "r"(end_addr), - /* %2 */ "r"(_graybuf->plane_size), - /* %3 */ "r"(pat_ptr), - /* %4 */ "r"(mask) - : /* clobbers */ - "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12" - ); -} - -/* References to C library routines used in _writeblock */ -asm ( - ".align 2 \n" -".ashlsi3: \n" /* C library routine: */ - ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */ -".lshrsi3: \n" /* C library routine: */ - ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */ - /* both routines preserve r4, destroy r5 and take ~16 cycles */ -); - -/* Invert pixels within an 8-pixel block. - * Address is the byte in the first bitplane, mask and bits determine which - * pixels to invert ('And'ed together, for matching the parameters with - * _writeblock) */ -static void _invertblock(unsigned char *address, unsigned mask, unsigned bits) -{ - bits &= mask; - if (!bits) - return; - - asm volatile ( - "mov #0,r1 \n" /* current_plane = 0 */ - - ".im_loop: \n" - "mov.b @%1,r2 \n" /* get data byte */ - "add #1,r1 \n" /* current_plane++; */ - "xor %2,r2 \n" /* invert bits */ - "mov.b r2,@%1 \n" /* store data byte */ - "add %3,%1 \n" /* advance address to next bitplane */ - "cmp/hi r1,%0 \n" /* current_plane < depth ? */ - "bt .im_loop \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(_graybuf->depth), - /* %1 */ "r"(address), - /* %2 */ "r"(bits), - /* %3 */ "r"(_graybuf->plane_size) - : /* clobbers */ - "r1", "r2", "macl" - ); -} - -/* Call _writeblock with the mask modified to draw foreground pixels only */ -static void _writeblockfg(unsigned char *address, unsigned mask, unsigned bits) -{ - mask &= bits; - if (mask) - _writeblock(address, mask, bits); -} - -/* Call _writeblock with the mask modified to draw background pixels only */ -static void _writeblockbg(unsigned char *address, unsigned mask, unsigned bits) -{ - mask &= ~bits; - if (mask) - _writeblock(address, mask, bits); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_clear_display.c b/apps/plugins/lib/gray_clear_display.c deleted file mode 100644 index 835107a7fe..0000000000 --- a/apps/plugins/lib/gray_clear_display.c +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_clear_display() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Clear the grayscale display (sets all pixels to white) - ---------------------------------------------------------------------------- - */ -void gray_clear_display(void) -{ - _gray_rb->memset(_graybuf->data, 0, MULU16(_graybuf->depth, - _graybuf->plane_size)); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c index b582cd801a..18b9c3c821 100644 --- a/apps/plugins/lib/gray_core.c +++ b/apps/plugins/lib/gray_core.c @@ -7,13 +7,13 @@ * \/ \/ \/ \/ \/ * $Id$ * -* Grayscale framework -* Core functions +* Greyscale framework +* Core & miscellaneous functions * * This is a generic framework to use grayscale display within Rockbox * plugins. It obviously does not work for the player. * -* Copyright (C) 2004 Jens Arnold +* Copyright (C) 2004-2005 Jens Arnold * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -31,28 +31,28 @@ /* Global variables */ struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ -_tGraybuf *_graybuf = NULL; /* pointer to grayscale buffer */ +struct _gray_info _gray_info; /* global info structure */ short _gray_random_buffer; /* buffer for random number generator */ /* Prototypes */ static void _timer_isr(void); -/* timer interrupt handler: display next bitplane */ +/* Timer interrupt handler: display next bitplane */ static void _timer_isr(void) { - _gray_rb->lcd_blit(_graybuf->data + MULU16(_graybuf->plane_size, - _graybuf->cur_plane), _graybuf->x, _graybuf->by, - _graybuf->width, _graybuf->bheight, _graybuf->width); + _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size, + _gray_info.cur_plane), _gray_info.x, _gray_info.by, + _gray_info.width, _gray_info.bheight, _gray_info.width); - if (++_graybuf->cur_plane >= _graybuf->depth) - _graybuf->cur_plane = 0; + if (++_gray_info.cur_plane >= _gray_info.depth) + _gray_info.cur_plane = 0; - if (_graybuf->flags & _GRAY_DEFERRED_UPDATE) /* lcd_update() requested? */ + if (_gray_info.flags & _GRAY_DEFERRED_UPDATE) /* lcd_update() requested? */ { - int x1 = MAX(_graybuf->x, 0); - int x2 = MIN(_graybuf->x + _graybuf->width, LCD_WIDTH); - int y1 = MAX(_graybuf->by << 3, 0); - int y2 = MIN((_graybuf->by << 3) + _graybuf->height, LCD_HEIGHT); + int x1 = MAX(_gray_info.x, 0); + int x2 = MIN(_gray_info.x + _gray_info.width, LCD_WIDTH); + int y1 = MAX(_gray_info.by << _PBLOCK_EXP, 0); + int y2 = MIN((_gray_info.by << _PBLOCK_EXP) + _gray_info.height, LCD_HEIGHT); if (y1 > 0) /* refresh part above overlay, full width */ _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); @@ -66,90 +66,108 @@ static void _timer_isr(void) if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */ _gray_rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1); - _graybuf->flags &= ~_GRAY_DEFERRED_UPDATE; /* clear request */ + _gray_info.flags &= ~_GRAY_DEFERRED_UPDATE; /* clear request */ } } -/*--------------------------------------------------------------------------- - Initialize the framework - ---------------------------------------------------------------------------- - Every framework needs such a function, and it has to be called as - the very first one */ -void gray_init(struct plugin_api* newrb) -{ - _gray_rb = newrb; -} +/* Initialise the framework and prepare the greyscale display buffer -/*--------------------------------------------------------------------------- - Prepare the grayscale display buffer - ---------------------------------------------------------------------------- arguments: + newrb = pointer to plugin api gbuf = pointer to the memory area to use (e.g. plugin buffer) gbuf_size = max usable size of the buffer - width = width in pixels (1..112) - bheight = height in 8-pixel units (1..8) - depth = desired number of shades - 1 (1..32) + buffered = use chunky pixel buffering with delta buffer? + This allows to use all drawing functions, but needs more + memory. Unbuffered operation provides only a subset of + drawing functions. (only gray_bitmap drawing and scrolling) + width = width in pixels (1..LCD_WIDTH) + bheight = height in LCD pixel-block units (8 pixels for b&w LCD, + 4 pixels for 4-grey LCD) (1..LCD_HEIGHT/block_size) + depth = number of bitplanes to use (1..32 for b&w LCD, 1..16 for + 4-grey LCD). result: = depth if there was enough memory < depth if there wasn't enough memory. The number of displayable shades is smaller than desired, but it still works - = 0 if there wasn't even enough memory for 1 bitplane (black & white) + = 0 if there wasn't even enough memory for 1 bitplane - You can request any depth from 1 to 32, not just powers of 2. The routine - performs "graceful degradation" if the memory is not sufficient for the - desired depth. As long as there is at least enough memory for 1 bitplane, - it creates as many bitplanes as fit into memory, although 1 bitplane will - only deliver black & white display. + You can request any depth in the allowed range, not just powers of 2. The + routine performs "graceful degradation" if the memory is not sufficient for + the desired depth. As long as there is at least enough memory for 1 bitplane, + it creates as many bitplanes as fit into memory, although 1 bitplane won't + deliver an enhancement over the native display. + + The number of displayable shades is calculated as follows: + b&w LCD: shades = depth + 1 + 4-grey LCD: shades = 3 * depth + 1 - If you need info about the memory taken by the grayscale buffer, supply an - int* as the last parameter. This int will then contain the number of bytes - used. The total memory needed can be calculated as follows: - total_mem = - sizeof(_tGraybuf) (= 64 bytes currently) - + sizeof(long) (= 4 bytes) - + (width * bheight + sizeof(long)) * depth - + 0..3 (longword alignment of grayscale display buffer) - */ -int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, - int bheight, int depth, int *buf_taken) + If you need info about the memory taken by the greyscale buffer, supply a + long* as the last parameter. This long will then contain the number of bytes + used. The total memory needed can be calculated as follows: + total_mem = + shades * sizeof(long) (bitpatterns) + + (width * bheight) * depth (bitplane data) + + buffered ? (chunky front- & backbuffer) + (width * bheight * 8(4) * 2) : 0 + + 0..3 (longword alignment) */ +int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, + bool buffered, int width, int bheight, int depth, long *buf_taken) { - int possible_depth, plane_size; - int i, j, align; + int possible_depth, i, j; + long plane_size, buftaken; + + _gray_rb = newrb; if ((unsigned) width > LCD_WIDTH - || (unsigned) bheight > (LCD_HEIGHT/8) + || (unsigned) bheight > (LCD_HEIGHT/_PBLOCK) || depth < 1) return 0; /* the buffer has to be long aligned */ - align = 3 - (((unsigned long)gbuf + 3) & 3); - gbuf += align; - gbuf_size -= align; + buftaken = (-(long)gbuf) & 3; + gbuf += buftaken; + + /* chunky front- & backbuffer */ + if (buffered) + { + plane_size = MULU16(width, bheight << _PBLOCK_EXP); + buftaken += 2 * plane_size; + if (buftaken > gbuf_size) + return 0; + + _gray_info.cur_buffer = gbuf; + gbuf += plane_size; + /* set backbuffer to 0xFF to guarantee the initial full update */ + _gray_rb->memset(gbuf, 0xFF, plane_size); + _gray_info.back_buffer = gbuf; + gbuf += plane_size; + } plane_size = MULU16(width, bheight); - possible_depth = (gbuf_size - sizeof(_tGraybuf) - sizeof(long)) - / (plane_size + sizeof(long)); + possible_depth = (gbuf_size - buftaken - sizeof(long)) + / (plane_size + _LEVEL_FAC * sizeof(long)); if (possible_depth < 1) return 0; - depth = MIN(depth, 32); + depth = MIN(depth, _MAX_DEPTH); depth = MIN(depth, possible_depth); - _graybuf = (_tGraybuf *) gbuf; /* global pointer to buffer structure */ - - _graybuf->x = 0; - _graybuf->by = 0; - _graybuf->width = width; - _graybuf->height = bheight << 3; - _graybuf->bheight = bheight; - _graybuf->plane_size = plane_size; - _graybuf->depth = depth; - _graybuf->cur_plane = 0; - _graybuf->flags = 0; - _graybuf->bitpattern = (unsigned long *) (gbuf + sizeof(_tGraybuf)); - _graybuf->data = (unsigned char *) (_graybuf->bitpattern + depth + 1); + _gray_info.x = 0; + _gray_info.by = 0; + _gray_info.width = width; + _gray_info.height = bheight << _PBLOCK_EXP; + _gray_info.bheight = bheight; + _gray_info.plane_size = plane_size; + _gray_info.depth = depth; + _gray_info.cur_plane = 0; + _gray_info.flags = 0; + _gray_info.plane_data = gbuf; + gbuf += depth * plane_size; + _gray_info.bitpattern = (unsigned long *)gbuf; + buftaken += depth * plane_size + + (_LEVEL_FAC * depth + 1) * sizeof(long); i = depth - 1; j = 8; @@ -158,12 +176,10 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, i >>= 1; j--; } - _graybuf->randmask = 0xFFu >> j; + _gray_info.randmask = 0xFFu >> j; - /* initial state is all white */ - _gray_rb->memset(_graybuf->data, 0, MULU16(depth, plane_size)); - /* Precalculate the bit patterns for all possible pixel values */ +#if LCD_DEPTH == 1 for (i = 0; i <= depth; i++) { unsigned long pattern = 0; @@ -181,72 +197,492 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, } /* now the lower bits contain the pattern */ - _graybuf->bitpattern[i] = pattern; + _gray_info.bitpattern[i] = pattern; } - - _graybuf->fg_pattern = _graybuf->bitpattern[0]; /* black */ - _graybuf->bg_pattern = _graybuf->bitpattern[depth]; /* white */ - _graybuf->drawmode = GRAY_DRAW_SOLID; - _graybuf->curfont = FONT_SYSFIXED; +#elif LCD_DEPTH == 2 + for (i = 0; i < depth; i++) + { + unsigned long pattern = 0; + int value = 0; + + for (j = 0; j < depth; j++) + { + pattern <<= 2; + value += i; + + if (value >= depth) + value -= depth; + else + pattern |= 3; + } + + _gray_info.bitpattern[i] = pattern | (~pattern & 0xaaaaaaaa); + _gray_info.bitpattern[i+depth] = (pattern & 0xaaaaaaaa) + | (~pattern & 0x55555555); + _gray_info.bitpattern[i+2*depth] = pattern & 0x55555555; + } + _gray_info.bitpattern[3*depth] = 0; +#endif /* LCD_DEPTH */ + + _gray_info.fg_brightness = 0; + _gray_info.bg_brightness = _LEVEL_FAC * depth; + _gray_info.drawmode = DRMODE_SOLID; + _gray_info.curfont = FONT_SYSFIXED; if (buf_taken) /* caller requested info about space taken */ - { - *buf_taken = sizeof(_tGraybuf) + sizeof(long) - + MULU16(plane_size + sizeof(long), depth) + align; - } + *buf_taken = buftaken; return depth; } -/*--------------------------------------------------------------------------- - Release the grayscale display buffer - ---------------------------------------------------------------------------- - Switches the grayscale overlay off at first if it is still running, - then sets the pointer to NULL. - DO CALL either this function or at least gray_show_display(false) - before you exit, otherwise nasty things may happen. - */ -void gray_release_buffer(void) +/* Release the greyscale display buffer and the library + DO CALL either this function or at least gray_show_display(false) + before you exit, otherwise nasty things may happen. */ +void gray_release(void) { - gray_show_display(false); - _graybuf = NULL; + gray_show(false); } -/*--------------------------------------------------------------------------- - Switch the grayscale overlay on or off - ---------------------------------------------------------------------------- - enable = true: the grayscale overlay is switched on if initialized - = false: the grayscale overlay is switched off and the regular lcd - content is restored - - DO NOT call lcd_update() or any other api function that directly accesses - the lcd while the grayscale overlay is running! If you need to do - lcd_update() to update something outside the grayscale overlay area, use - gray_deferred_update() instead. +/* Switch the greyscale overlay on or off + DO NOT call lcd_update() or any other api function that directly accesses + the lcd while the greyscale overlay is running! If you need to do + lcd_update() to update something outside the greyscale overlay area, use + gray_deferred_update() instead. Other functions to avoid are: lcd_blit() (obviously), lcd_update_rect(), lcd_set_contrast(), - lcd_set_invert_display(), lcd_set_flip(), lcd_roll() - - The grayscale display consumes ~50 % CPU power (for a full screen overlay, - less if the overlay is smaller) when switched on. You can switch the overlay - on and off as many times as you want. - */ -void gray_show_display(bool enable) + lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */ +void gray_show(bool enable) { if (enable) { - _graybuf->flags |= _GRAY_RUNNING; + _gray_info.flags |= _GRAY_RUNNING; _gray_rb->plugin_register_timer(FREQ / 67, 1, _timer_isr); } else { _gray_rb->plugin_unregister_timer(); - _graybuf->flags &= ~_GRAY_RUNNING; + _gray_info.flags &= ~_GRAY_RUNNING; _gray_rb->lcd_update(); /* restore whatever there was before */ } } -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR +/* Update a rectangular area of the greyscale overlay */ +void gray_update_rect(int x, int y, int width, int height) +{ + int ymax; + long srcofs; + unsigned char *dst; + + if (width <= 0) + return; /* nothing to do */ + + /* The Y coordinates have to work on whole pixel block rows */ + ymax = (y + height - 1) >> _PBLOCK_EXP; + y >>= _PBLOCK_EXP; + + if (x + width > _gray_info.width) + width = _gray_info.width - x; + if (ymax >= _gray_info.bheight) + ymax = _gray_info.bheight - 1; + + srcofs = (y << _PBLOCK_EXP) + MULU16(_gray_info.height, x); + dst = _gray_info.plane_data + MULU16(_gray_info.width, y) + x; + + /* Copy specified rectange bitmap to hardware */ + for (; y <= ymax; y++) + { + long srcofs_row = srcofs; + unsigned char *dst_row = dst; + unsigned char *dst_end = dst_row + width; + + do + { +#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) + unsigned mask; + unsigned long change; + unsigned long pat_stack[8]; + unsigned long *pat_ptr; + unsigned char *end_addr; + + asm ( + "mov.l @(%3,%1),r1 \n" + "mov.l @(%3,%2),r2 \n" + "xor r1,r2 \n" + "add #4,%3 \n" + "mov.l @(%3,%1),r1 \n" + "mov.l @(%3,%2),%0 \n" + "xor r1,%0 \n" + "or r2,%0 \n" + : /* outputs */ + /* %0 */ "=r"(change) + : /* inputs */ + /* %1 */ "r"(_gray_info.cur_buffer), + /* %2 */ "r"(_gray_info.back_buffer), + /* %3 */ "z"(srcofs_row) + : /* clobbers */ + "r1", "r2" + ); + + if (change != 0) + { + pat_ptr = &pat_stack[8]; + + /* precalculate the bit patterns with random shifts + * for all 8 pixels and put them on an extra "stack" */ + asm volatile ( + "add %5,%3 \n" + "add %5,%4 \n" + "mov #8,r3 \n" /* loop count in r3: 8 pixels */ + + ".ur_pre_loop: \n" + "mov.b @%3+,r0 \n" /* read current buffer */ + "mov.b @%4,r1 \n" /* read back buffer */ + "mov #0,r2 \n" /* preset for skipped pixel */ + "mov.b r0,@%4 \n" /* update back buffer */ + "add #1,%4 \n" + "cmp/eq r0,r1 \n" /* no change? */ + "bt .ur_skip \n" /* -> skip */ + + "shll2 r0 \n" /* pixel value -> pattern offset */ + "mov.l @(r0,%7),r4 \n" /* r4 = bitpattern[byte]; */ + + "mov #75,r0 \n" + "mulu r0,%0 \n" /* multiply by 75 */ + "sts macl,%0 \n" + "add #74,%0 \n" /* add another 74 */ + /* Since the lower bits are not very random: */ + "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */ + "and %8,r1 \n" /* mask out unneeded bits */ + + "cmp/hs %6,r1 \n" /* random >= depth ? */ + "bf .ur_ntrim \n" + "sub %6,r1 \n" /* yes: random -= depth; */ + ".ur_ntrim: \n" + + "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ + "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ + "mov r1,r5 \n" + + "mov %6,r5 \n" + "sub r1,r5 \n" /* r5 = depth - r1 */ + "mov.l .lshrsi3,r1 \n" + "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ + "mov r0,r2 \n" /* store previous result in r2 */ + + "or r0,r2 \n" /* rotated_pattern = r2 | r0 */ + "clrt \n" /* mask bit = 0 (replace) */ + + ".ur_skip: \n" /* T == 1 if skipped */ + "rotcr %2 \n" /* get mask bit */ + "mov.l r2,@-%1 \n" /* push on pattern stack */ + + "add #-1,r3 \n" /* decrease loop count */ + "cmp/pl r3 \n" /* loop count > 0? */ + "bt .ur_pre_loop\n" /* yes: loop */ + "shlr8 %2 \n" + "shlr16 %2 \n" + : /* outputs */ + /* %0, in & out */ "+r"(_gray_random_buffer), + /* %1, in & out */ "+r"(pat_ptr), + /* %2 */ "=&r"(mask) + : /* inputs */ + /* %3 */ "r"(_gray_info.cur_buffer), + /* %4 */ "r"(_gray_info.back_buffer), + /* %5 */ "2"(srcofs_row), + /* %6 */ "r"(_gray_info.depth), + /* %7 */ "r"(_gray_info.bitpattern), + /* %8 */ "r"(_gray_info.randmask) + : /* clobbers */ + "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr" + ); + + end_addr = dst_row + MULU16(_gray_info.depth, _gray_info.plane_size); + + /* set the bits for all 8 pixels in all bytes according to the + * precalculated patterns on the pattern stack */ + asm ( + "mov.l @%3+,r1 \n" /* pop all 8 patterns */ + "mov.l @%3+,r2 \n" + "mov.l @%3+,r3 \n" + "mov.l @%3+,r6 \n" + "mov.l @%3+,r7 \n" + "mov.l @%3+,r8 \n" + "mov.l @%3+,r9 \n" + "mov.l @%3+,r10 \n" + + "tst %4,%4 \n" /* nothing to keep? */ + "bt .ur_sloop \n" /* yes: jump to short loop */ + + ".ur_floop: \n" /** full loop (there are bits to keep)**/ + "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ + "rotcl r0 \n" /* rotate t bit into r0 */ + "shlr r2 \n" + "rotcl r0 \n" + "shlr r3 \n" + "rotcl r0 \n" + "shlr r6 \n" + "rotcl r0 \n" + "shlr r7 \n" + "rotcl r0 \n" + "shlr r8 \n" + "rotcl r0 \n" + "shlr r9 \n" + "rotcl r0 \n" + "shlr r10 \n" + "mov.b @%0,%3 \n" /* read old value */ + "rotcl r0 \n" + "and %4,%3 \n" /* mask out unneeded bits */ + "or r0,%3 \n" /* set new bits */ + "mov.b %3,@%0 \n" /* store value to bitplane */ + "add %2,%0 \n" /* advance to next bitplane */ + "cmp/hi %0,%1 \n" /* last bitplane done? */ + "bt .ur_floop \n" /* no: loop */ + + "bra .ur_end \n" + "nop \n" + + ".ur_sloop: \n" /** short loop (nothing to keep) **/ + "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ + "rotcl r0 \n" /* rotate t bit into r0 */ + "shlr r2 \n" + "rotcl r0 \n" + "shlr r3 \n" + "rotcl r0 \n" + "shlr r6 \n" + "rotcl r0 \n" + "shlr r7 \n" + "rotcl r0 \n" + "shlr r8 \n" + "rotcl r0 \n" + "shlr r9 \n" + "rotcl r0 \n" + "shlr r10 \n" + "rotcl r0 \n" + "mov.b r0,@%0 \n" /* store byte to bitplane */ + "add %2,%0 \n" /* advance to next bitplane */ + "cmp/hi %0,%1 \n" /* last bitplane done? */ + "bt .ur_sloop \n" /* no: loop */ + + ".ur_end: \n" + : /* outputs */ + : /* inputs */ + /* %0 */ "r"(dst_row), + /* %1 */ "r"(end_addr), + /* %2 */ "r"(_gray_info.plane_size), + /* %3 */ "r"(pat_ptr), + /* %4 */ "r"(mask) + : /* clobbers */ + "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10" + ); + } +#endif + srcofs_row += _gray_info.height; + dst_row++; + } + while (dst_row < dst_end); + + srcofs += _PBLOCK; + dst += _gray_info.width; + } +} + +#if CONFIG_CPU == SH7034 +/* References to C library routines used in gray_update_rect() */ +asm ( + ".align 2 \n" +".ashlsi3: \n" /* C library routine: */ + ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */ +".lshrsi3: \n" /* C library routine: */ + ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */ + /* both routines preserve r4, destroy r5 and take ~16 cycles */ +); +#endif + +/* Update the whole greyscale overlay */ +void gray_update(void) +{ + gray_update_rect(0, 0, _gray_info.width, _gray_info.height); +} + +/* Do an lcd_update() to show changes done by rb->lcd_xxx() functions + (in areas of the screen not covered by the greyscale overlay). */ +void gray_deferred_lcd_update(void) +{ + if (_gray_info.flags & _GRAY_RUNNING) + _gray_info.flags |= _GRAY_DEFERRED_UPDATE; + else + _gray_rb->lcd_update(); +} + +/*** Screenshot ***/ + +#define BMP_NUMCOLORS (_MAX_DEPTH * _LEVEL_FAC + 1) +#define BMP_BPP 8 +#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3) +#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS) +#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT) +#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE) + +#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff +#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff + +static const unsigned char bmpheader[] = +{ + 0x42, 0x4d, /* 'BM' */ + LE32_CONST(BMP_TOTALSIZE), /* Total file size */ + 0x00, 0x00, 0x00, 0x00, /* Reserved */ + LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */ + + 0x28, 0x00, 0x00, 0x00, /* Size of (2nd) header */ + LE32_CONST(LCD_WIDTH), /* Width in pixels */ + LE32_CONST(LCD_HEIGHT), /* Height in pixels */ + 0x01, 0x00, /* Number of planes (always 1) */ + LE16_CONST(BMP_BPP), /* Bits per pixel 1/4/8/16/24 */ + 0x00, 0x00, 0x00, 0x00, /* Compression mode, 0 = none */ + LE32_CONST(BMP_DATASIZE), /* Size of bitmap data */ + 0xc4, 0x0e, 0x00, 0x00, /* Horizontal resolution (pixels/meter) */ + 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */ + LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */ + LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */ +}; + +#if LCD_DEPTH == 1 +#define BMP_RED 0x90 +#define BMP_GREEN 0xee +#define BMP_BLUE 0x90 +#elif LCD_DEPTH == 2 +#define BMP_RED 0xad +#define BMP_GREEN 0xd8 +#define BMP_BLUE 0xe6 +#endif + +static unsigned char linebuf[BMP_LINESIZE]; + +/* Save the current display content (b&w and greyscale overlay) to an 8-bit + * BMP file in the root directory. */ +void gray_screendump(void) +{ + int fh, i, bright; + int x, y, by, mask; + int gx, gby; + unsigned char *lcdptr, *grayptr, *grayptr2; + char filename[MAX_PATH]; + +#ifdef HAVE_RTC + struct tm *tm = _gray_rb->get_time(); + + _gray_rb->snprintf(filename, MAX_PATH, + "/graydump %04d-%02d-%02d %02d-%02d-%02d.bmp", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +#else + { + DIR* dir; + int max_dump_file = 1; /* default to graydump_0001.bmp */ + dir = _gray_rb->opendir("/"); + if (dir) /* found */ + { + /* Search for the highest screendump filename present, + increment behind that. So even with "holes" + (deleted files), the newest will always have the + highest number. */ + while(true) + { + struct dirent* entry; + int curr_dump_file; + /* walk through the directory content */ + entry = _gray_rb->readdir(dir); + if (!entry) + { + _gray_rb->closedir(dir); + break; /* end of dir */ + } + if (_gray_rb->strncasecmp(entry->d_name, "graydump_", 9)) + continue; /* no screendump file */ + curr_dump_file = _gray_rb->atoi(&entry->d_name[9]); + if (curr_dump_file >= max_dump_file) + max_dump_file = curr_dump_file + 1; + } + } + _gray_rb->snprintf(filename, MAX_PATH, "/graydump_%04d.bmp", + max_dump_file); + } +#endif + + fh = _gray_rb->creat(filename, O_WRONLY); + + if (fh < 0) + return; + + _gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */ + + /* build clut, always 33 entries */ + linebuf[3] = 0; + + for (i = 0; i < BMP_NUMCOLORS; i++) + { + bright = MIN(i, _LEVEL_FAC * _gray_info.depth); + linebuf[0] = MULU16(BMP_BLUE, bright) / (_LEVEL_FAC * _gray_info.depth); + linebuf[1] = MULU16(BMP_GREEN, bright) / (_LEVEL_FAC * _gray_info.depth); + linebuf[2] = MULU16(BMP_RED, bright) / (_LEVEL_FAC * _gray_info.depth); + _gray_rb->write(fh, linebuf, 4); + } + + /* 8-bit BMP image goes bottom -> top */ + for (y = LCD_HEIGHT - 1; y >= 0; y--) + { +#if LCD_DEPTH == 1 + _gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH); + + mask = 1 << (y & 7); + by = y >> 3; + lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); + gby = by - _gray_info.by; + + if ((_gray_info.flags & _GRAY_RUNNING) + && (unsigned) gby < (unsigned) _gray_info.bheight) + { + /* line contains greyscale (and maybe b&w) graphics */ + grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby); + + for (x = 0; x < LCD_WIDTH; x++) + { + if (*lcdptr++ & mask) + linebuf[x] = 0; + + gx = x - _gray_info.x; + + if ((unsigned)gx < (unsigned)_gray_info.width) + { + bright = 0; + grayptr2 = grayptr + gx; + + for (i = 0; i < _gray_info.depth; i++) + { + if (!(*grayptr2 & mask)) + bright++; + grayptr2 += _gray_info.plane_size; + } + linebuf[x] = bright; + } + } + } + else + { + /* line contains only b&w graphics */ + for (x = 0; x < LCD_WIDTH; x++) + if (*lcdptr++ & mask) + linebuf[x] = 0; + } +#endif + + _gray_rb->write(fh, linebuf, sizeof(linebuf)); + } + + _gray_rb->close(fh); +} + +#endif /* HAVE_LCD_BITMAP */ +#endif /* !SIMULATOR */ diff --git a/apps/plugins/lib/gray_deferred_update.c b/apps/plugins/lib/gray_deferred_update.c deleted file mode 100644 index 3b6edd869e..0000000000 --- a/apps/plugins/lib/gray_deferred_update.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_deferred_update() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Do an lcd_update() to show changes done by rb->lcd_xxx() functions (in areas - of the screen not covered by the grayscale overlay). - ---------------------------------------------------------------------------- - If the grayscale overlay is running, the update will be done in the next - call of the interrupt routine, otherwise it will be performed right away. - See also comment for the gray_show_display() function. - */ -void gray_deferred_update(void) -{ - if (_graybuf->flags & _GRAY_RUNNING) - _graybuf->flags |= _GRAY_DEFERRED_UPDATE; - else - _gray_rb->lcd_update(); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c new file mode 100644 index 0000000000..0742459d4b --- /dev/null +++ b/apps/plugins/lib/gray_draw.c @@ -0,0 +1,826 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Greyscale framework +* Drawing functions for buffered mode +* +* This is a generic framework to use grayscale display within Rockbox +* plugins. It obviously does not work for the player. +* +* Copyright (C) 2004-2005 Jens Arnold +* +* All files in this archive are subject to the GNU General Public License. +* See the file COPYING in the source tree root for full license agreement. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#ifndef SIMULATOR /* not for simulator by now */ +#include "plugin.h" + +#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#include "gray.h" + +/*** low-level drawing functions ***/ + +static void setpixel(unsigned char *address) +{ + *address = _gray_info.fg_brightness; +} + +static void clearpixel(unsigned char *address) +{ + *address = _gray_info.bg_brightness; +} + +static void flippixel(unsigned char *address) +{ + *address = _LEVEL_FAC * _gray_info.depth - *address; +} + +static void nopixel(unsigned char *address) +{ + (void)address; +} + +void (* const _gray_pixelfuncs[8])(unsigned char *address) = { + flippixel, nopixel, setpixel, setpixel, + nopixel, clearpixel, nopixel, clearpixel +}; + +/*** Drawing functions ***/ + +/* Clear the whole display */ +void gray_clear_display(void) +{ + int brightness = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + _gray_info.fg_brightness : _gray_info.bg_brightness; + + _gray_rb->memset(_gray_info.cur_buffer, brightness, + MULU16(_gray_info.width, _gray_info.height)); +} + +/* Set a single pixel */ +void gray_drawpixel(int x, int y) +{ + if (((unsigned)x < (unsigned)_gray_info.width) + && ((unsigned)y < (unsigned)_gray_info.height)) + _gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(x, + _gray_info.height) + y]); +} + +/* Draw a line */ +void gray_drawline(int x1, int y1, int x2, int y2) +{ + int numpixels; + int i; + int deltax, deltay; + int d, dinc1, dinc2; + int x, xinc1, xinc2; + int y, yinc1, yinc2; + void (*pfunc)(unsigned char *address) = _gray_pixelfuncs[_gray_info.drawmode]; + + deltax = abs(x2 - x1); + deltay = abs(y2 - y1); + xinc2 = 1; + yinc2 = 1; + + if (deltax >= deltay) + { + numpixels = deltax; + d = 2 * deltay - deltax; + dinc1 = deltay * 2; + dinc2 = (deltay - deltax) * 2; + xinc1 = 1; + yinc1 = 0; + } + else + { + numpixels = deltay; + d = 2 * deltax - deltay; + dinc1 = deltax * 2; + dinc2 = (deltax - deltay) * 2; + xinc1 = 0; + yinc1 = 1; + } + numpixels++; /* include endpoints */ + + if (x1 > x2) + { + xinc1 = -xinc1; + xinc2 = -xinc2; + } + + if (y1 > y2) + { + yinc1 = -yinc1; + yinc2 = -yinc2; + } + + x = x1; + y = y1; + + for (i = 0; i < numpixels; i++) + { + if (((unsigned)x < (unsigned)_gray_info.width) + && ((unsigned)y < (unsigned)_gray_info.height)) + pfunc(&_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]); + + if (d < 0) + { + d += dinc1; + x += xinc1; + y += yinc1; + } + else + { + d += dinc2; + x += xinc2; + y += yinc2; + } + } +} + +/* Draw a horizontal line (optimised) */ +void gray_hline(int x1, int x2, int y) +{ + int x; + unsigned char *dst, *dst_end; + void (*pfunc)(unsigned char *address); + + /* direction flip */ + if (x2 < x1) + { + x = x1; + x1 = x2; + x2 = x; + } + + /* nothing to draw? */ + if (((unsigned)y >= (unsigned)_gray_info.height) + || (x1 >= _gray_info.width) || (x2 < 0)) + return; + + /* clipping */ + if (x1 < 0) + x1 = 0; + if (x2 >= _gray_info.width) + x2 = _gray_info.width - 1; + + pfunc = _gray_pixelfuncs[_gray_info.drawmode]; + dst = &_gray_info.cur_buffer[MULU16(x1, _gray_info.height) + y]; + + dst_end = dst + MULU16(x2 - x1, _gray_info.height); + do + { + pfunc(dst); + dst += _gray_info.height; + } + while (dst <= dst_end); +} + +/* Draw a vertical line (optimised) */ +void gray_vline(int x, int y1, int y2) +{ + int y, bits; + unsigned char *dst; + bool fillopt; + void (*pfunc)(unsigned char *address); + + /* direction flip */ + if (y2 < y1) + { + y = y1; + y1 = y2; + y2 = y; + } + + /* nothing to draw? */ + if (((unsigned)x >= (unsigned)_gray_info.width) + || (y1 >= _gray_info.height) || (y2 < 0)) + return; + + /* clipping */ + if (y1 < 0) + y1 = 0; + if (y2 >= _gray_info.height) + y2 = _gray_info.height - 1; + + bits = _gray_info.fg_brightness; + fillopt = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + (_gray_info.drawmode & DRMODE_BG) : + (_gray_info.drawmode & DRMODE_FG); + if (fillopt &&(_gray_info.drawmode & DRMODE_INVERSEVID)) + bits = _gray_info.bg_brightness; + + pfunc = _gray_pixelfuncs[_gray_info.drawmode]; + dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y1]; + + if (fillopt) + _gray_rb->memset(dst, bits, y2 - y1 + 1); + else + { + unsigned char *dst_end = dst + y2 - y1; + do + pfunc(dst++); + while (dst <= dst_end); + } +} + +/* Draw a rectangular box */ +void gray_drawrect(int x, int y, int width, int height) +{ + if ((width <= 0) || (height <= 0)) + return; + + int x2 = x + width - 1; + int y2 = y + height - 1; + + gray_vline(x, y, y2); + gray_vline(x2, y, y2); + gray_hline(x, x2, y); + gray_hline(x, x2, y2); +} + +/* Fill a rectangular area */ +void gray_fillrect(int x, int y, int width, int height) +{ + int bits; + unsigned char *dst, *dst_end; + bool fillopt; + void (*pfunc)(unsigned char *address); + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= _gray_info.width) + || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + x = 0; + } + if (y < 0) + { + height += y; + y = 0; + } + if (x + width > _gray_info.width) + width = _gray_info.width - x; + if (y + height > _gray_info.height) + height = _gray_info.height - y; + + bits = _gray_info.fg_brightness; + fillopt = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + (_gray_info.drawmode & DRMODE_BG) : + (_gray_info.drawmode & DRMODE_FG); + if (fillopt &&(_gray_info.drawmode & DRMODE_INVERSEVID)) + bits = _gray_info.bg_brightness; + + pfunc = _gray_pixelfuncs[_gray_info.drawmode]; + dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; + dst_end = dst + MULU16(width, _gray_info.height); + + do + { + if (fillopt) + _gray_rb->memset(dst, bits, height); + else + { + unsigned char *dst_col = dst; + unsigned char *col_end = dst_col + height; + + do + pfunc(dst_col++); + while (dst_col < col_end); + } + dst += _gray_info.height; + } + while (dst < dst_end); +} + +/* Draw a filled triangle */ +void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) +{ + int x, y; + long fp_y1, fp_y2, fp_dy1, fp_dy2; + + /* sort vertices by increasing x value */ + if (x1 > x3) + { + if (x2 < x3) /* x2 < x3 < x1 */ + { + x = x1; x1 = x2; x2 = x3; x3 = x; + y = y1; y1 = y2; y2 = y3; y3 = y; + } + else if (x2 > x1) /* x3 < x1 < x2 */ + { + x = x1; x1 = x3; x3 = x2; x2 = x; + y = y1; y1 = y3; y3 = y2; y2 = y; + } + else /* x3 <= x2 <= x1 */ + { + x = x1; x1 = x3; x3 = x; + y = y1; y1 = y3; y3 = y; + } + } + else + { + if (x2 < x1) /* x2 < x1 <= x3 */ + { + x = x1; x1 = x2; x2 = x; + y = y1; y1 = y2; y2 = y; + } + else if (x2 > x3) /* x1 <= x3 < x2 */ + { + x = x2; x2 = x3; x3 = x; + y = y2; y2 = y3; y3 = y; + } + /* else already sorted */ + } + + if (x1 < x3) /* draw */ + { + fp_dy1 = ((y3 - y1) << 16) / (x3 - x1); + fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1); + + if (x1 < x2) /* first part */ + { + fp_dy2 = ((y2 - y1) << 16) / (x2 - x1); + fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1); + for (x = x1; x < x2; x++) + { + gray_vline(x, fp_y1 >> 16, fp_y2 >> 16); + fp_y1 += fp_dy1; + fp_y2 += fp_dy2; + } + } + if (x2 < x3) /* second part */ + { + fp_dy2 = ((y3 - y2) << 16) / (x3 - x2); + fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1); + for (x = x2; x < x3; x++) + { + gray_vline(x, fp_y1 >> 16, fp_y2 >> 16); + fp_y1 += fp_dy1; + fp_y2 += fp_dy2; + } + } + } +} + +/* About Rockbox' internal monochrome bitmap format: + * + * A bitmap contains one bit for every pixel that defines if that pixel is + * foreground (1) or background (0). Bits within a byte are arranged + * vertically, LSB at top. + * The bytes are stored in row-major order, with byte 0 being top left, + * byte 1 2nd from left etc. The first row of bytes defines pixel rows + * 0..7, the second row defines pixel row 8..15 etc. + * + * This is similar to the internal lcd hw format. */ + +/* Draw a partial monochrome bitmap */ +void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) +{ + const unsigned char *src_end; + unsigned char *dst, *dst_end; + void (*fgfunc)(unsigned char *address); + void (*bgfunc)(unsigned char *address); + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= _gray_info.width) + || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + src_x -= x; + x = 0; + } + if (y < 0) + { + height += y; + src_y -= y; + y = 0; + } + if (x + width > _gray_info.width) + width = _gray_info.width - x; + if (y + height > _gray_info.height) + height = _gray_info.height - y; + + src += MULU16(stride, src_y >> 3) + src_x; /* move starting point */ + src_y &= 7; + src_end = src + width; + + dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; + fgfunc = _gray_pixelfuncs[_gray_info.drawmode]; + bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID]; + + do + { + const unsigned char *src_col = src++; + unsigned char *dst_col = dst; + unsigned char data = *src_col >> src_y; + int numbits = 8 - src_y; + + dst_end = dst_col + height; + do + { + if (data & 0x01) + fgfunc(dst_col++); + else + bgfunc(dst_col++); + + data >>= 1; + if (--numbits == 0) + { + src_col += stride; + data = *src_col; + numbits = 8; + } + } + while (dst_col < dst_end); + + dst += _gray_info.height; + } + while (src < src_end); +} + +/* Draw a full monochrome bitmap */ +void gray_mono_bitmap(const unsigned char *src, int x, int y, int width, int height) +{ + gray_mono_bitmap_part(src, 0, 0, width, x, y, width, height); +} + +/* Draw a partial greyscale bitmap, canonical format */ +void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) +{ + const unsigned char *src_end; + unsigned char *dst, *dst_end; + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= _gray_info.width) + || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + src_x -= x; + x = 0; + } + if (y < 0) + { + height += y; + src_y -= y; + y = 0; + } + if (x + width > _gray_info.width) + width = _gray_info.width - x; + if (y + height > _gray_info.height) + height = _gray_info.height - y; + + src += MULU16(stride, src_y) + src_x; /* move starting point */ + src_end = src + width; + dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]; + + do + { + const unsigned char *src_col = src++; + unsigned char *dst_col = dst; + + dst_end = dst_col + height; + do + { + unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, *src_col) + 127; + *dst_col++ = (data + (data >> 8)) >> 8; /* approx. data / 255 */ + src_col += stride; + } + while (dst_col < dst_end); + + dst += _gray_info.height; + } + while (src < src_end); +} + +/* Draw a full greyscale bitmap, canonical format */ +void gray_gray_bitmap(const unsigned char *src, int x, int y, int width, + int height) +{ + gray_gray_bitmap_part(src, 0, 0, width, x, y, width, height); +} + +/* Put a string at a given pixel position, skipping first ofs pixel columns */ +void gray_putsxyofs(int x, int y, int ofs, const unsigned char *str) +{ + int ch; + struct font* pf = font_get(_gray_info.curfont); + + while ((ch = *str++) != '\0' && x < _gray_info.width) + { + int width; + const unsigned char *bits; + + /* check input range */ + if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) + ch = pf->defaultchar; + ch -= pf->firstchar; + + /* get proportional width and glyph bits */ + width = pf->width ? pf->width[ch] : pf->maxwidth; + + if (ofs > width) + { + ofs -= width; + continue; + } + + bits = pf->bits + (pf->offset ? + pf->offset[ch] : ((pf->height + 7) / 8 * pf->maxwidth * ch)); + + gray_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); + + x += width - ofs; + ofs = 0; + } +} + +/* Put a string at a given pixel position */ +void gray_putsxy(int x, int y, const unsigned char *str) +{ + gray_putsxyofs(x, y, 0, str); +} + +/*** Unbuffered drawing functions ***/ + +/* Clear the greyscale display (sets all pixels to white) */ +void gray_ub_clear_display(void) +{ + _gray_rb->memset(_gray_info.plane_data, 0, MULU16(_gray_info.depth, + _gray_info.plane_size)); +} + +/* Write a pixel block, defined by their brightnesses in a greymap. + Address is the byte in the first bitplane, src is the greymap start address, + stride is the increment for the greymap to get to the next pixel, mask + determines which pixels of the destination block are changed. For "0" bits, + the src address is not incremented! */ +static void _writearray(unsigned char *address, const unsigned char *src, + int stride, unsigned mask) +{ +#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) + unsigned long pat_stack[8]; + unsigned long *pat_ptr = &pat_stack[8]; + unsigned char *end_addr; + + /* precalculate the bit patterns with random shifts + for all 8 pixels and put them on an extra "stack" */ + asm ( + "mov #8,r3 \n" /* loop count in r3: 8 pixels */ + "mov %7,r2 \n" /* copy mask -- gcc bug workaround */ + + ".wa_loop: \n" /** load pattern for pixel **/ + "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */ + "shlr r2 \n" /* shift out lsb of mask */ + "bf .wa_skip \n" /* skip this pixel */ + + "mov.b @%2,r0 \n" /* load src byte */ + "extu.b r0,r0 \n" /* extend unsigned */ + "mulu %4,r0 \n" /* macl = byte * depth; */ + "sts macl,r1 \n" /* r1 = macl; */ + "add #127,r1 \n" /* byte += 127; */ + "mov r1,r0 \n" + "shlr8 r1 \n" + "add r1,r0 \n" /* byte += byte >> 8; */ + "shlr8 r0 \n" /* byte >>= 8; */ + "shll2 r0 \n" + "mov.l @(r0,%5),r4 \n" /* r4 = bitpattern[byte]; */ + + "mov #75,r0 \n" + "mulu r0,%0 \n" /* multiply by 75 */ + "sts macl,%0 \n" + "add #74,%0 \n" /* add another 74 */ + /* Since the lower bits are not very random: */ + "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */ + "and %6,r1 \n" /* mask out unneeded bits */ + + "cmp/hs %4,r1 \n" /* random >= depth ? */ + "bf .wa_ntrim \n" + "sub %4,r1 \n" /* yes: random -= depth; */ + ".wa_ntrim: \n" + + "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ + "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ + "mov r1,r5 \n" + + "mov %4,r5 \n" + "sub r1,r5 \n" /* r5 = depth - r1 */ + "mov.l .lshrsi3,r1 \n" + "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ + "mov r0,r1 \n" /* store previous result in r1 */ + + "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ + + ".wa_skip: \n" + "mov.l r0,@-%1 \n" /* push on pattern stack */ + + "add %3,%2 \n" /* src += stride; */ + "add #-1,r3 \n" /* decrease loop count */ + "cmp/pl r3 \n" /* loop count > 0? */ + "bt .wa_loop \n" /* yes: loop */ + : /* outputs */ + /* %0, in & out */ "+r"(_gray_random_buffer), + /* %1, in & out */ "+r"(pat_ptr) + : /* inputs */ + /* %2 */ "r"(src), + /* %3 */ "r"(stride), + /* %4 */ "r"(_gray_info.depth), + /* %5 */ "r"(_gray_info.bitpattern), + /* %6 */ "r"(_gray_info.randmask), + /* %7 */ "r"(mask) + : /* clobbers */ + "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr" + ); + + end_addr = address + MULU16(_gray_info.depth, _gray_info.plane_size); + + /* set the bits for all 8 pixels in all bytes according to the + * precalculated patterns on the pattern stack */ + asm ( + "mov.l @%3+,r1 \n" /* pop all 8 patterns */ + "mov.l @%3+,r2 \n" + "mov.l @%3+,r3 \n" + "mov.l @%3+,r8 \n" + "mov.l @%3+,r9 \n" + "mov.l @%3+,r10 \n" + "mov.l @%3+,r11 \n" + "mov.l @%3+,r12 \n" + + "not %4,%4 \n" /* "set" mask -> "keep" mask */ + "extu.b %4,%4 \n" /* mask out high bits */ + "tst %4,%4 \n" /* nothing to keep? */ + "bt .wa_sloop \n" /* yes: jump to short loop */ + + ".wa_floop: \n" /** full loop (there are bits to keep)**/ + "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ + "rotcl r0 \n" /* rotate t bit into r0 */ + "shlr r2 \n" + "rotcl r0 \n" + "shlr r3 \n" + "rotcl r0 \n" + "shlr r8 \n" + "rotcl r0 \n" + "shlr r9 \n" + "rotcl r0 \n" + "shlr r10 \n" + "rotcl r0 \n" + "shlr r11 \n" + "rotcl r0 \n" + "shlr r12 \n" + "mov.b @%0,%3 \n" /* read old value */ + "rotcl r0 \n" + "and %4,%3 \n" /* mask out unneeded bits */ + "or r0,%3 \n" /* set new bits */ + "mov.b %3,@%0 \n" /* store value to bitplane */ + "add %2,%0 \n" /* advance to next bitplane */ + "cmp/hi %0,%1 \n" /* last bitplane done? */ + "bt .wa_floop \n" /* no: loop */ + + "bra .wa_end \n" + "nop \n" + + ".wa_sloop: \n" /** short loop (nothing to keep) **/ + "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ + "rotcl r0 \n" /* rotate t bit into r0 */ + "shlr r2 \n" + "rotcl r0 \n" + "shlr r3 \n" + "rotcl r0 \n" + "shlr r8 \n" + "rotcl r0 \n" + "shlr r9 \n" + "rotcl r0 \n" + "shlr r10 \n" + "rotcl r0 \n" + "shlr r11 \n" + "rotcl r0 \n" + "shlr r12 \n" + "rotcl r0 \n" + "mov.b r0,@%0 \n" /* store byte to bitplane */ + "add %2,%0 \n" /* advance to next bitplane */ + "cmp/hi %0,%1 \n" /* last bitplane done? */ + "bt .wa_sloop \n" /* no: loop */ + + ".wa_end: \n" + : /* outputs */ + : /* inputs */ + /* %0 */ "r"(address), + /* %1 */ "r"(end_addr), + /* %2 */ "r"(_gray_info.plane_size), + /* %3 */ "r"(pat_ptr), + /* %4 */ "r"(mask) + : /* clobbers */ + "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12" + ); +#endif +} + +#if CONFIG_CPU == SH7034 +/* References to C library routines used in _writearray() */ +asm ( + ".align 2 \n" +".ashlsi3: \n" /* C library routine: */ + ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */ +".lshrsi3: \n" /* C library routine: */ + ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */ + /* both routines preserve r4, destroy r5 and take ~16 cycles */ +); +#endif + +/* Draw a partial greyscale bitmap, canonical format */ +void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, + int stride, int x, int y, int width, int height) +{ + int shift, ny; + unsigned char *dst, *dst_end; + unsigned mask, mask_bottom; + + /* nothing to draw? */ + if ((width <= 0) || (height <= 0) || (x >= _gray_info.width) + || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0)) + return; + + /* clipping */ + if (x < 0) + { + width += x; + src_x -= x; + x = 0; + } + if (y < 0) + { + height += y; + src_y -= y; + y = 0; + } + if (x + width > _gray_info.width) + width = _gray_info.width - x; + if (y + height > _gray_info.height) + height = _gray_info.height - y; + + shift = y & (_PBLOCK-1); + src += MULU16(stride, src_y) + src_x - MULU16(stride, shift); + dst = _gray_info.plane_data + x + + MULU16(_gray_info.width, y >> _PBLOCK_EXP); + ny = height - 1 + shift; + + mask = 0xFFu << shift; /* ATTN LCD_DEPTH == 2 */ + mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1)); + + for (; ny >= _PBLOCK; ny -= _PBLOCK) + { + const unsigned char *src_row = src; + unsigned char *dst_row = dst; + + dst_end = dst_row + width; + do + _writearray(dst_row++, src_row++, stride, mask); + while (dst_row < dst_end); + + src += stride << _PBLOCK_EXP; + dst += _gray_info.width; + mask = 0xFFu; + } + mask &= mask_bottom; + dst_end = dst + width; + do + _writearray(dst++, src++, stride, mask); + while (dst < dst_end); +} + +/* Draw a full greyscale bitmap, canonical format */ +void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width, + int height) +{ + gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height); +} + + +#endif /* HAVE_LCD_BITMAP */ +#endif /* !SIMULATOR */ + diff --git a/apps/plugins/lib/gray_drawbitmap.c b/apps/plugins/lib/gray_drawbitmap.c deleted file mode 100644 index 376f76d45e..0000000000 --- a/apps/plugins/lib/gray_drawbitmap.c +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_drawbitmap() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Display a bitmap with the current drawinfo - ---------------------------------------------------------------------------- - The drawmode is used as described for gray_set_drawmode() - - This (now) uses the same bitmap format as the core b&w graphics routines, - so you can use bmp2rb to generate bitmaps for use with this function as - well. - - A bitmap contains one bit for every pixel that defines if that pixel is - foreground (1) or background (0). Bits within a byte are arranged - vertically, LSB at top. - The bytes are stored in row-major order, with byte 0 being top left, - byte 1 2nd from left etc. The first row of bytes defines pixel rows - 0..7, the second row defines pixel row 8..15 etc. - - The parameter is useful if you want to show only a part of a - bitmap. It should always be set to the "row length" of the bitmap. - */ -void gray_drawbitmap(const unsigned char *src, int x, int y, int nx, int ny, - int stride) -{ - int shift; - unsigned bits, mask_top, mask_bottom; - const unsigned char *src_col; - unsigned char *dst, *dst_col; - void (*blockfunc)(unsigned char *address, unsigned mask, unsigned bits); - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */ - ny = _graybuf->height - y; - - if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */ - nx = _graybuf->width - x; - - dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3); - shift = y & 7; - ny += shift; - - mask_top = 0xFFu << (y & 7); - mask_bottom = ~(0xFEu << ((ny - 1) & 7)); - if (ny <= 8) - mask_bottom &= mask_top; - - blockfunc = _gray_blockfuncs[_graybuf->drawmode]; - - for(x = 0; x < nx; x++) - { - src_col = src++; - dst_col = dst++; - bits = 0; - y = 0; - - if (ny > 8) - { - bits = *src_col << shift; - src_col += stride; - - blockfunc(dst_col, mask_top, bits); - dst_col += _graybuf->width; - bits >>= 8; - - for (y = 8; y < ny - 8; y += 8) - { - bits |= *src_col << shift; - src_col += stride; - - blockfunc(dst_col, 0xFFu, bits); - dst_col += _graybuf->width; - bits >>= 8; - } - } - if (y + shift < ny) - bits |= *src_col << shift; - - blockfunc(dst_col, mask_bottom, bits); - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_drawgraymap.c b/apps/plugins/lib/gray_drawgraymap.c deleted file mode 100644 index 2760d5a96c..0000000000 --- a/apps/plugins/lib/gray_drawgraymap.c +++ /dev/null @@ -1,275 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_drawgraymap() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/* Prototypes */ -static void _writearray(unsigned char *address, const unsigned char *src, - int stride, unsigned mask); - -/* Write an 8-pixel block, defined by their brightnesses in a graymap. - * Address is the byte in the first bitplane, src is the graymap start address, - * stride is the increment for the graymap to get to the next pixel, mask - * determines which pixels of the destination block are changed. For "0" bits, - * the src address is not incremented! */ -static void _writearray(unsigned char *address, const unsigned char *src, - int stride, unsigned mask) -{ - unsigned long pat_stack[8]; - register unsigned char *end_addr; - register unsigned long *pat_ptr = &pat_stack[8]; - - /* precalculate the bit patterns with random shifts (same RNG as - * _writepixel, see there for an explanation) for all 8 pixels and put them - * on an extra "stack" */ - asm ( - "mov #8,r3 \n" /* loop count in r3: 8 pixels */ - "mov %7,r2 \n" /* copy mask */ - - ".wa_loop: \n" /** load pattern for pixel **/ - "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */ - "shlr r2 \n" /* shift out lsb of mask */ - "bf .wa_skip \n" /* skip this pixel */ - - "mov.b @%2,r0 \n" /* load src byte */ - "extu.b r0,r0 \n" /* extend unsigned */ - "mulu %4,r0 \n" /* macl = byte * depth; */ - "add %3,%2 \n" /* src += stride; */ - "sts macl,r4 \n" /* r4 = macl; */ - "add r4,r0 \n" /* byte += r4; */ - "shlr8 r0 \n" /* byte >>= 8; */ - "shll2 r0 \n" - "mov.l @(r0,%5),r4 \n" /* r4 = bitpattern[byte]; */ - - "mov #75,r0 \n" - "mulu r0,%0 \n" /* multiply by 75 */ - "sts macl,%0 \n" - "add #74,%0 \n" /* add another 74 */ - /* Since the lower bits are not very random: */ - "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */ - "and %6,r1 \n" /* mask out unneeded bits */ - - "cmp/hs %4,r1 \n" /* random >= depth ? */ - "bf .wa_ntrim \n" - "sub %4,r1 \n" /* yes: random -= depth; */ - ".wa_ntrim: \n" - - "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ - "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ - "mov r1,r5 \n" - - "mov %4,r5 \n" - "sub r1,r5 \n" /* r5 = depth - r1 */ - "mov.l .lshrsi3,r1 \n" - "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ - "mov r0,r1 \n" /* store previous result in r1 */ - - "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ - - ".wa_skip: \n" - "mov.l r0,@-%1 \n" /* push on pattern stack */ - - "add #-1,r3 \n" /* decrease loop count */ - "cmp/pl r3 \n" /* loop count > 0? */ - "bt .wa_loop \n" /* yes: loop */ - : /* outputs */ - /* %0, in & out */ "+r"(_gray_random_buffer), - /* %1, in & out */ "+r"(pat_ptr) - : /* inputs */ - /* %2 */ "r"(src), - /* %3 */ "r"(stride), - /* %4 */ "r"(_graybuf->depth), - /* %5 */ "r"(_graybuf->bitpattern), - /* %6 */ "r"(_graybuf->randmask), - /* %7 */ "r"(mask) - : /* clobbers */ - "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr" - ); - - end_addr = address + MULU16(_graybuf->depth, _graybuf->plane_size); - - /* set the bits for all 8 pixels in all bytes according to the - * precalculated patterns on the pattern stack */ - asm volatile ( - "mov.l @%3+,r1 \n" /* pop all 8 patterns */ - "mov.l @%3+,r2 \n" - "mov.l @%3+,r3 \n" - "mov.l @%3+,r8 \n" - "mov.l @%3+,r9 \n" - "mov.l @%3+,r10 \n" - "mov.l @%3+,r11 \n" - "mov.l @%3+,r12 \n" - - "not %4,%4 \n" /* "set" mask -> "keep" mask */ - "extu.b %4,%4 \n" /* mask out high bits */ - "tst %4,%4 \n" /* nothing to keep? */ - "bt .wa_sloop \n" /* yes: jump to short loop */ - - ".wa_floop: \n" /** full loop (there are bits to keep)**/ - "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ - "rotcl r0 \n" /* rotate t bit into r0 */ - "shlr r2 \n" - "rotcl r0 \n" - "shlr r3 \n" - "rotcl r0 \n" - "shlr r8 \n" - "rotcl r0 \n" - "shlr r9 \n" - "rotcl r0 \n" - "shlr r10 \n" - "rotcl r0 \n" - "shlr r11 \n" - "rotcl r0 \n" - "shlr r12 \n" - "mov.b @%0,%3 \n" /* read old value */ - "rotcl r0 \n" - "and %4,%3 \n" /* mask out unneeded bits */ - "or r0,%3 \n" /* set new bits */ - "mov.b %3,@%0 \n" /* store value to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ - "bt .wa_floop \n" /* no: loop */ - - "bra .wa_end \n" - "nop \n" - - ".wa_sloop: \n" /** short loop (nothing to keep) **/ - "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ - "rotcl r0 \n" /* rotate t bit into r0 */ - "shlr r2 \n" - "rotcl r0 \n" - "shlr r3 \n" - "rotcl r0 \n" - "shlr r8 \n" - "rotcl r0 \n" - "shlr r9 \n" - "rotcl r0 \n" - "shlr r10 \n" - "rotcl r0 \n" - "shlr r11 \n" - "rotcl r0 \n" - "shlr r12 \n" - "rotcl r0 \n" - "mov.b r0,@%0 \n" /* store byte to bitplane */ - "add %2,%0 \n" /* advance to next bitplane */ - "cmp/hi %0,%1 \n" /* last bitplane done? */ - "bt .wa_sloop \n" /* no: loop */ - - ".wa_end: \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(address), - /* %1 */ "r"(end_addr), - /* %2 */ "r"(_graybuf->plane_size), - /* %3 */ "r"(pat_ptr), - /* %4 */ "r"(mask) - : /* clobbers */ - "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12" - ); -} - -/* References to C library routines used in _writearray */ -asm ( - ".align 2 \n" -".ashlsi3: \n" /* C library routine: */ - ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */ -".lshrsi3: \n" /* C library routine: */ - ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */ - /* both routines preserve r4, destroy r5 and take ~16 cycles */ -); - -/*--------------------------------------------------------------------------- - Copy a grayscale bitmap into the display - ---------------------------------------------------------------------------- - A grayscale bitmap contains one byte for every pixel that defines the - brightness of the pixel (0..255). Bytes are read in row-major order. - The parameter is useful if you want to show only a part of a - bitmap. It should always be set to the "row length" of the bitmap, so - for displaying the whole bitmap, nx == stride. - - This is the only drawing function NOT using the drawinfo. - */ -void gray_drawgraymap(const unsigned char *src, int x, int y, int nx, int ny, - int stride) -{ - int shift; - unsigned mask_top, mask_bottom; - const unsigned char *src_row; - unsigned char *dst, *dst_row; - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */ - ny = _graybuf->height - y; - - if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */ - nx = _graybuf->width - x; - - dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3); - shift = y & 7; - ny += shift; - - mask_top = 0xFFu << (y & 7); - mask_bottom = ~(0xFEu << ((ny - 1) & 7)); - if (ny <= 8) - mask_bottom &= mask_top; - - if (ny > 8) - { - src_row = src; - dst_row = dst; - - for (x = 0; x < nx; x++) - _writearray(dst_row++, src_row++, stride, mask_top); - - src += MULU16(stride, 8 - shift); - dst += _graybuf->width; - - for (y = 8; y < ny - 8; y += 8) - { - src_row = src; - dst_row = dst; - - for (x = 0; x < nx; x++) - _writearray(dst_row++, src_row++, stride, 0xFFu); - - src += stride << 3; - dst += _graybuf->width; - } - } - - for (x = 0; x < nx; x++) - _writearray(dst++, src++, stride, mask_bottom); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_drawline.c b/apps/plugins/lib/gray_drawline.c deleted file mode 100644 index 5ec4967c14..0000000000 --- a/apps/plugins/lib/gray_drawline.c +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_drawline() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Draw a line from (x1, y1) to (x2, y2) with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - */ -void gray_drawline(int x1, int y1, int x2, int y2) -{ - int numpixels; - int i; - int deltax, deltay; - int d, dinc1, dinc2; - int x, xinc1, xinc2; - int y, yinc1, yinc2; - unsigned long pattern; - void (*pixelfunc)(int x, int y, unsigned long pattern); - - if ((unsigned) x1 >= (unsigned) _graybuf->width - || (unsigned) y1 >= (unsigned) _graybuf->height - || (unsigned) x2 >= (unsigned) _graybuf->width - || (unsigned) y2 >= (unsigned) _graybuf->height) - return; - - deltax = abs(x2 - x1); - deltay = abs(y2 - y1); - xinc2 = 1; - yinc2 = 1; - - if (deltax >= deltay) - { - numpixels = deltax; - d = 2 * deltay - deltax; - dinc1 = deltay * 2; - dinc2 = (deltay - deltax) * 2; - xinc1 = 1; - yinc1 = 0; - } - else - { - numpixels = deltay; - d = 2 * deltax - deltay; - dinc1 = deltax * 2; - dinc2 = (deltax - deltay) * 2; - xinc1 = 0; - yinc1 = 1; - } - numpixels++; /* include endpoints */ - - if (x1 > x2) - { - xinc1 = -xinc1; - xinc2 = -xinc2; - } - - if (y1 > y2) - { - yinc1 = -yinc1; - yinc2 = -yinc2; - } - - x = x1; - y = y1; - - pixelfunc = _gray_pixelfuncs[_graybuf->drawmode]; - pattern = (_graybuf->drawmode == GRAY_DRAW_BG) ? - _graybuf->bg_pattern : _graybuf->fg_pattern; - - for (i = 0; i < numpixels; i++) - { - pixelfunc(x, y, pattern); - - if (d < 0) - { - d += dinc1; - x += xinc1; - y += yinc1; - } - else - { - d += dinc2; - x += xinc2; - y += yinc2; - } - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_drawpixel.c b/apps/plugins/lib/gray_drawpixel.c deleted file mode 100644 index f7601f4360..0000000000 --- a/apps/plugins/lib/gray_drawpixel.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_drawpixel() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set a pixel with the current drawinfo - ---------------------------------------------------------------------------- - If the drawmode is GRAY_DRAW_INVERSE, the pixel is inverted - GRAY_DRAW_FG and GRAY_DRAW_SOLID draw the pixel in the foreground shade - GRAY_DRAW_BG draws the pixel in the background shade - */ -void gray_drawpixel(int x, int y) -{ - unsigned long pattern; - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - pattern = (_graybuf->drawmode == GRAY_DRAW_BG) ? - _graybuf->bg_pattern : _graybuf->fg_pattern; - - _gray_pixelfuncs[_graybuf->drawmode](x, y, pattern); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_drawrect.c b/apps/plugins/lib/gray_drawrect.c deleted file mode 100644 index bd0bb71852..0000000000 --- a/apps/plugins/lib/gray_drawrect.c +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_drawrect() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Draw a (hollow) rectangle with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - */ -void gray_drawrect(int x, int y, int nx, int ny) -{ - int x2, y2; - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */ - ny = _graybuf->height - y; - - if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */ - nx = _graybuf->width - x; - - x2 = x + nx - 1; - y2 = y + ny - 1; - - gray_horline(x, x2, y); - gray_horline(x, x2, y2); - gray_verline(x, y, y2); - gray_verline(x2, y, y2); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_fillrect.c b/apps/plugins/lib/gray_fillrect.c deleted file mode 100644 index ac6d4818b9..0000000000 --- a/apps/plugins/lib/gray_fillrect.c +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_fillrect() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Draw a filled rectangle with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - - This one uses the block drawing optimization, so it is rather fast. - */ -void gray_fillrect(int x, int y, int nx, int ny) -{ - int shift; - unsigned bits, mask_top, mask_bottom; - unsigned char *dst, *dst_row; - void (*blockfunc)(unsigned char *address, unsigned mask, unsigned bits); - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */ - ny = _graybuf->height - y; - - if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */ - nx = _graybuf->width - x; - - dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3); - shift = y & 7; - ny += shift; - - mask_top = 0xFFu << (y & 7); - mask_bottom = ~(0xFEu << ((ny - 1) & 7)); - if (ny <= 8) - mask_bottom &= mask_top; - - blockfunc = _gray_blockfuncs[_graybuf->drawmode]; - bits = (_graybuf->drawmode == GRAY_DRAW_BG) ? 0u : 0xFFu; - - if (ny > 8) - { - dst_row = dst; - for (x = 0; x < nx; x++) - blockfunc(dst_row++, mask_top, bits); - - dst += _graybuf->width; - - for (y = 8; y < ny - 8; y += 8) - { - dst_row = dst; - for (x = 0; x < nx; x++) - blockfunc(dst_row++, 0xFFu, bits); - - dst += _graybuf->width; - } - } - - for (x = 0; x < nx; x++) - blockfunc(dst++, mask_bottom, bits); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_getstringsize.c b/apps/plugins/lib/gray_getstringsize.c deleted file mode 100644 index 5b6d3e7c49..0000000000 --- a/apps/plugins/lib/gray_getstringsize.c +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_getstringsize() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Calculate width and height of the given text in pixels when rendered with - the currently selected font. - ---------------------------------------------------------------------------- - This works exactly the same way as the core lcd_getstringsize(), only that - it uses the selected font for grayscale. - */ -int gray_getstringsize(const unsigned char *str, int *w, int *h) -{ - int ch; - int width = 0; - struct font *pf = _graybuf->curfont; - - while ((ch = *str++)) - { - /* check input range */ - if (ch < pf->firstchar || ch >= pf->firstchar + pf->size) - ch = pf->defaultchar; - ch -= pf->firstchar; - - /* get proportional width */ - width += pf->width ? pf->width[ch] : pf->maxwidth; - } - if (w) - *w = width; - if (h) - *h = pf->height; - return width; -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_horline.c b/apps/plugins/lib/gray_horline.c deleted file mode 100644 index c5ad0046de..0000000000 --- a/apps/plugins/lib/gray_horline.c +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_horline() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Draw a horizontal line from (x1, y) to (x2, y) with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - */ -void gray_horline(int x1, int x2, int y) -{ - int x; - unsigned long pattern; - void (*pixelfunc)(int x, int y, unsigned long pattern); - - if ((unsigned) x1 >= (unsigned) _graybuf->width - || (unsigned) x2 >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - if (x1 > x2) - { - x = x1; - x1 = x2; - x2 = x; - } - pixelfunc = _gray_pixelfuncs[_graybuf->drawmode]; - pattern = (_graybuf->drawmode == GRAY_DRAW_BG) ? - _graybuf->bg_pattern : _graybuf->fg_pattern; - - for (x = x1; x <= x2; x++) - pixelfunc(x, y, pattern); - -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_parm.c b/apps/plugins/lib/gray_parm.c new file mode 100644 index 0000000000..c66cc33339 --- /dev/null +++ b/apps/plugins/lib/gray_parm.c @@ -0,0 +1,107 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Greyscale framework +* Parameter handling +* +* This is a generic framework to use grayscale display within Rockbox +* plugins. It obviously does not work for the player. +* +* Copyright (C) 2004-2005 Jens Arnold +* +* All files in this archive are subject to the GNU General Public License. +* See the file COPYING in the source tree root for full license agreement. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#ifndef SIMULATOR /* not for simulator by now */ +#include "plugin.h" + +#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#include "gray.h" + +/* Set position of the top left corner of the greyscale overlay + Note that by is in pixel-block units (8 on Archos/SH1, 4 on H1x0) */ +void gray_set_position(int x, int by) +{ + _gray_info.x = x; + _gray_info.by = by; + + if (_gray_info.flags & _GRAY_RUNNING) + _gray_info.flags |= _GRAY_DEFERRED_UPDATE; +} + +/* Set the draw mode for subsequent drawing operations */ +void gray_set_drawmode(int mode) +{ + _gray_info.drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); +} + +/* Return the current draw mode */ +int gray_get_drawmode(void) +{ + return _gray_info.drawmode; +} + +/* Set the foreground shade for subsequent drawing operations */ +void gray_set_foreground(int brightness) +{ + unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, brightness & 0xFF) + 127; + + _gray_info.fg_brightness = (data + (data >> 8)) >> 8; /* approx. data / 255 */ +} + +/* Return the current foreground shade */ +int gray_get_foreground(void) +{ + return (_gray_info.fg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1)) + / (_LEVEL_FAC * _gray_info.depth); +} + +/* Set the background shade for subsequent drawing operations */ +void gray_set_background(int brightness) +{ + unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, brightness & 0xFF) + 127; + + _gray_info.bg_brightness = (data + (data >> 8)) >> 8; /* approx. data / 255 */ +} + +/* Return the current background shade */ +int gray_get_background(void) +{ + return (_gray_info.bg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1)) + / (_LEVEL_FAC * _gray_info.depth); +} + +/* Set draw mode, foreground and background shades at once */ +void gray_set_drawinfo(int mode, int fg_brightness, int bg_brightness) +{ + gray_set_drawmode(mode); + gray_set_foreground(fg_brightness); + gray_set_background(bg_brightness); +} + +/* Set font for the text output routines */ +void gray_setfont(int newfont) +{ + _gray_info.curfont = newfont; +} + +/* Get width and height of a text when printed with the current font */ +int gray_getstringsize(const unsigned char *str, int *w, int *h) +{ + return _gray_rb->font_getstringsize(str, w, h, _gray_info.curfont); +} + +#endif /* HAVE_LCD_BITMAP */ +#endif /* !SIMULATOR */ + diff --git a/apps/plugins/lib/gray_pixelfuncs.c b/apps/plugins/lib/gray_pixelfuncs.c deleted file mode 100644 index 31ce8deb3c..0000000000 --- a/apps/plugins/lib/gray_pixelfuncs.c +++ /dev/null @@ -1,245 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* Low level pixel drawing functions -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/* Prototypes */ -static void _writepixel(int x, int y, unsigned long pattern); -static void _invertpixel(int x, int y, unsigned long pattern); - -/* function pointer array */ -void (* const _gray_pixelfuncs[4])(int x, int y, unsigned long pattern) = { - _invertpixel, _writepixel, _writepixel, _writepixel -}; - -/* Set a pixel to a specific bit pattern (low level routine) */ -static void _writepixel(int x, int y, unsigned long pattern) -{ - register unsigned mask, random; - register unsigned char *address; - - /* Some (pseudo-)random function must be used here to shift the bit - * pattern randomly, otherwise you would get flicker and/or moire. - * Since rand() is relatively slow, I've implemented a simple, but very - * fast pseudo-random generator based on linear congruency in assembler. - * It delivers max. 16 pseudo-random bits in each iteration. */ - - /* simple but fast pseudo-random generator */ - asm ( - "mov #75,r1 \n" - "mulu %1,r1 \n" /* multiply by 75 */ - "sts macl,%1 \n" /* get result */ - "add #74,%1 \n" /* add another 74 */ - /* Since the lower bits are not very random: */ - "swap.b %1,%0 \n" /* get bits 8..15 (need max. 5) */ - "and %2,%0 \n" /* mask out unneeded bits */ - : /* outputs */ - /* %0 */ "=&r"(random), - /* %1, in & out */ "+r"(_gray_random_buffer) - : /* inputs */ - /* %2 */ "r"(_graybuf->randmask) - : /* clobbers */ - "r1", "macl" - ); - - /* precalculate mask and byte address in first bitplane */ - asm ( - "mov %3,%0 \n" /* take y as base for address offset */ - "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */ - "shlr %0 \n" - "mulu %0,%2 \n" /* multiply with width */ - "and #7,%3 \n" /* get lower 3 bits of y */ - "sts macl,%0 \n" /* get mulu result */ - "add %4,%0 \n" /* add base + x to get final address */ - - "mov %3,%1 \n" /* move lower 3 bits of y out of r0 */ - "mova .wp_masktable,%3\n" /* get address of mask table in r0 */ - "bra .wp_predone \n" /* skip the table */ - "mov.b @(%3,%1),%1 \n" /* get entry from mask table */ - - ".align 2 \n" - ".wp_masktable: \n" /* mask table */ - ".byte 0x01 \n" - ".byte 0x02 \n" - ".byte 0x04 \n" - ".byte 0x08 \n" - ".byte 0x10 \n" - ".byte 0x20 \n" - ".byte 0x40 \n" - ".byte 0x80 \n" - - ".wp_predone: \n" - : /* outputs */ - /* %0 */ "=&r"(address), - /* %1 */ "=&r"(mask) - : /* inputs */ - /* %2 */ "r"(_graybuf->width), - /* %3 = r0 */ "z"(y), - /* %4 */ "r"(_graybuf->data + x) - : /* clobbers */ - "macl" - ); - - /* the hard part: set bits in all bitplanes according to pattern */ - asm volatile ( - "cmp/hs %1,%5 \n" /* random >= depth ? */ - "bf .wp_ntrim \n" - "sub %1,%5 \n" /* yes: random -= depth */ - /* it's sufficient to do this once, since the mask guarantees - * random < 2 * depth */ - ".wp_ntrim: \n" - - /* calculate some addresses */ - "mulu %4,%1 \n" /* end address offset */ - "not %3,r1 \n" /* get inverse mask (for "and") */ - "sts macl,%1 \n" /* result of mulu */ - "mulu %4,%5 \n" /* address offset of 'th plane */ - "add %2,%1 \n" /* end offset -> end address */ - "sts macl,%5 \n" /* result of mulu */ - "add %2,%5 \n" /* address of 'th plane */ - "bra .wp_start1 \n" - "mov %5,r2 \n" /* copy address */ - - /* first loop: set bits from 'th bitplane to last */ - ".wp_loop1: \n" - "mov.b @r2,r3 \n" /* get data byte */ - "shlr %0 \n" /* shift bit mask, sets t bit */ - "and r1,r3 \n" /* reset bit (-> "white") */ - "bf .wp_white1 \n" /* t=0? -> "white" bit */ - "or %3,r3 \n" /* set bit ("black" bit) */ - ".wp_white1: \n" - "mov.b r3,@r2 \n" /* store data byte */ - "add %4,r2 \n" /* advance address to next bitplane */ - ".wp_start1: \n" - "cmp/hi r2,%1 \n" /* address < end address ? */ - "bt .wp_loop1 \n" - - "bra .wp_start2 \n" - "nop \n" - - /* second loop: set bits from first to 'th bitplane - * Bit setting works the other way round here to equalize average - * execution times for bright and dark pixels */ - ".wp_loop2: \n" - "mov.b @%2,r3 \n" /* get data byte */ - "shlr %0 \n" /* shift bit mask, sets t bit */ - "or %3,r3 \n" /* set bit (-> "black") */ - "bt .wp_black2 \n" /* t=1? -> "black" bit */ - "and r1,r3 \n" /* reset bit ("white" bit) */ - ".wp_black2: \n" - "mov.b r3,@%2 \n" /* store data byte */ - "add %4,%2 \n" /* advance address to next bitplane */ - ".wp_start2: \n" - "cmp/hi %2,%5 \n" /* address < 'th address ? */ - "bt .wp_loop2 \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(pattern), - /* %1 */ "r"(_graybuf->depth), - /* %2 */ "r"(address), - /* %3 */ "r"(mask), - /* %4 */ "r"(_graybuf->plane_size), - /* %5 */ "r"(random) - : /* clobbers */ - "r1", "r2", "r3", "macl" - ); -} - -/* invert all bits for one pixel (low level routine) */ -static void _invertpixel(int x, int y, unsigned long pattern) -{ - register unsigned mask; - register unsigned char *address; - - (void) pattern; /* not used for invert */ - - /* precalculate mask and byte address in first bitplane */ - asm ( - "mov %3,%0 \n" /* take y as base for address offset */ - "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */ - "shlr %0 \n" - "mulu %0,%2 \n" /* multiply with width */ - "and #7,%3 \n" /* get lower 3 bits of y */ - "sts macl,%0 \n" /* get mulu result */ - "add %4,%0 \n" /* add base + x to get final address */ - - "mov %3,%1 \n" /* move lower 3 bits of y out of r0 */ - "mova .ip_masktable,%3\n" /* get address of mask table in r0 */ - "bra .ip_predone \n" /* skip the table */ - "mov.b @(%3,%1),%1 \n" /* get entry from mask table */ - - ".align 2 \n" - ".ip_masktable: \n" /* mask table */ - ".byte 0x01 \n" - ".byte 0x02 \n" - ".byte 0x04 \n" - ".byte 0x08 \n" - ".byte 0x10 \n" - ".byte 0x20 \n" - ".byte 0x40 \n" - ".byte 0x80 \n" - - ".ip_predone: \n" - : /* outputs */ - /* %0 */ "=&r"(address), - /* %1 */ "=&r"(mask) - : /* inputs */ - /* %2 */ "r"(_graybuf->width), - /* %3 = r0 */ "z"(y), - /* %4 */ "r"(_graybuf->data + x) - : /* clobbers */ - "macl" - ); - - /* invert bits in all bitplanes */ - asm volatile ( - "mov #0,r1 \n" /* current_plane = 0 */ - - ".ip_loop: \n" - "mov.b @%1,r2 \n" /* get data byte */ - "add #1,r1 \n" /* current_plane++; */ - "xor %2,r2 \n" /* invert bits */ - "mov.b r2,@%1 \n" /* store data byte */ - "add %3,%1 \n" /* advance address to next bitplane */ - "cmp/hi r1,%0 \n" /* current_plane < depth ? */ - "bt .ip_loop \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(_graybuf->depth), - /* %1 */ "r"(address), - /* %2 */ "r"(mask), - /* %3 */ "r"(_graybuf->plane_size) - : /* clobbers */ - "r1", "r2" - ); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_position_display.c b/apps/plugins/lib/gray_position_display.c deleted file mode 100644 index 4ec13ee730..0000000000 --- a/apps/plugins/lib/gray_position_display.c +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_position_display() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set position of the top left corner of the grayscale overlay - ---------------------------------------------------------------------------- - x = left margin in pixels - by = top margin in 8-pixel units - - You may set this in a way that the overlay spills across the right or - bottom display border. In this case it will simply be clipped by the - LCD controller. You can even set negative values, this will clip at the - left or top border. I did not test it, but the limits may be +127 / -128 - - If you use this while the grayscale overlay is running, the now-freed area - will be restored. - */ -void gray_position_display(int x, int by) -{ - _graybuf->x = x; - _graybuf->by = by; - - if (_graybuf->flags & _GRAY_RUNNING) - _graybuf->flags |= _GRAY_DEFERRED_UPDATE; -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_putsxy.c b/apps/plugins/lib/gray_putsxy.c deleted file mode 100644 index 9b34ad7a65..0000000000 --- a/apps/plugins/lib/gray_putsxy.c +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_putsxy() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Display text starting at (x, y) with the current font and drawinfo - ---------------------------------------------------------------------------- - The drawmode is used as described for gray_set_drawmode() - */ -void gray_putsxy(int x, int y, const unsigned char *str) -{ - int ch, width; - const unsigned char *bits; - struct font *pf = _graybuf->curfont; - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y >= (unsigned) _graybuf->height) - return; - - while ((ch = *str++) != '\0' && x < _graybuf->width) - { - /* check input range */ - if (ch < pf->firstchar || ch >= pf->firstchar + pf->size) - ch = pf->defaultchar; - ch -= pf->firstchar; - - /* get proportional width and glyph bits */ - width = pf->width ? pf->width[ch] : pf->maxwidth; - bits = pf->bits + (pf->offset ? pf->offset[ch] : - MULU16((pf->height + 7) / 8, MULU16(pf->maxwidth, ch))); - - gray_drawbitmap((const unsigned char*) bits, x, y, width, pf->height, - width); - x += width; - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_screendump.c b/apps/plugins/lib/gray_screendump.c deleted file mode 100644 index fdc88b8547..0000000000 --- a/apps/plugins/lib/gray_screendump.c +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_screendump() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -static const unsigned char bmpheader[] = -{ - 0x42, 0x4d, 0xba, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x00, - 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, - 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x21, 0x00, - 0x00, 0x00, 0x21, 0x00, 0x00, 0x00 -}; - -static unsigned char linebuf[LCD_WIDTH]; - -/*--------------------------------------------------------------------------- - Save the current display content (b&w and grayscale overlay) to an 8-bit - BMP file in the root directory - ---------------------------------------------------------------------------- - * - * This one is rather slow if used with larger bit depths, but it's intended - * primary use is for documenting the grayscale plugins. A much faster version - * would be possible, but would take more than twice the RAM - */ -void gray_screendump(void) -{ - int fh, i, bright; - int x, y, by, mask; - int gx, gby; - - char filename[MAX_PATH]; - struct tm *tm = _gray_rb->get_time(); - - unsigned char *lcdptr, *grayptr, *grayptr2; - - _gray_rb->snprintf(filename, MAX_PATH, - "/graydump %04d-%02d-%02d %02d-%02d-%02d.bmp", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - fh = _gray_rb->creat(filename, O_WRONLY); - - if (fh < 0) - return; - - _gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */ - - /* build clut, always 33 entries */ - - linebuf[3] = 0; - - for (i = 0; i < 33; i++) - { - bright = MIN(i, _graybuf->depth); - linebuf[0] = linebuf[2] = MULU16(0x90, bright) / _graybuf->depth; - linebuf[1] = MULU16(0xee, bright) / _graybuf->depth; - _gray_rb->write(fh, linebuf, 4); - } - - /* 8-bit BMP image goes bottom -> top */ - - for (y = LCD_HEIGHT - 1; y >= 0; y--) - { - _gray_rb->memset(linebuf, 32, sizeof(linebuf)); /* max. brightness */ - - mask = 1 << (y & 7); - by = y / 8; - lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); - gby = by - _graybuf->by; - - if ((_graybuf->flags & _GRAY_RUNNING) - && (unsigned) gby < (unsigned) _graybuf->bheight) - { - /* line contains grayscale (and maybe b&w) graphics */ - grayptr = _graybuf->data + MULU16(_graybuf->width, gby); - - for (x = 0; x < LCD_WIDTH; x++) - { - if (*lcdptr++ & mask) - linebuf[x] = 0; - - gx = x - _graybuf->x; - - if ((unsigned) gx < (unsigned) _graybuf->width) - { - bright = 0; - grayptr2 = grayptr + gx; - - for (i = 0; i < _graybuf->depth; i++) - { - if (!(*grayptr2 & mask)) - bright++; - grayptr2 += _graybuf->plane_size; - } - linebuf[x] = bright; - } - } - } - else - { - /* line contains only b&w graphics */ - for (x = 0; x < LCD_WIDTH; x++) - if (*lcdptr++ & mask) - linebuf[x] = 0; - } - - _gray_rb->write(fh, linebuf, sizeof(linebuf)); - } - - _gray_rb->close(fh); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_scroll.c b/apps/plugins/lib/gray_scroll.c new file mode 100644 index 0000000000..e4520e7649 --- /dev/null +++ b/apps/plugins/lib/gray_scroll.c @@ -0,0 +1,479 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* $Id$ +* +* Greyscale framework +* Scrolling routines +* +* This is a generic framework to use grayscale display within Rockbox +* plugins. It obviously does not work for the player. +* +* Copyright (C) 2004-2005 Jens Arnold +* +* All files in this archive are subject to the GNU General Public License. +* See the file COPYING in the source tree root for full license agreement. +* +* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +* KIND, either express or implied. +* +****************************************************************************/ + +#ifndef SIMULATOR /* not for simulator by now */ +#include "plugin.h" + +#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#include "gray.h" + +/* FIXME: intermediate solution until we have properly optimised memmove() */ +static void *my_memmove(void *dst0, const void *src0, size_t len0) +{ + char *dst = (char *) dst0; + char *src = (char *) src0; + + if (dst <= src) + { + while (len0--) + *dst++ = *src++; + } + else + { + dst += len0; + src += len0; + + while (len0--) + *(--dst) = *(--src); + } + + return dst0; +} + +/*** Scrolling ***/ + +/* Scroll left */ +void gray_scroll_left(int count) +{ + long shift, length; + int blank; + + if ((unsigned)count >= (unsigned)_gray_info.width) + return; + + shift = MULU16(_gray_info.height, count); + length = MULU16(_gray_info.height, _gray_info.width - count); + blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + _gray_info.fg_brightness : _gray_info.bg_brightness; + + my_memmove(_gray_info.cur_buffer, _gray_info.cur_buffer + shift, length); + _gray_rb->memset(_gray_info.cur_buffer + length, blank, shift); +} + +/* Scroll right */ +void gray_scroll_right(int count) +{ + long shift, length; + int blank; + + if ((unsigned)count >= (unsigned)_gray_info.width) + return; + + shift = MULU16(_gray_info.height, count); + length = MULU16(_gray_info.height, _gray_info.width - count); + blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + _gray_info.fg_brightness : _gray_info.bg_brightness; + + my_memmove(_gray_info.cur_buffer + shift, _gray_info.cur_buffer, length); + _gray_rb->memset(_gray_info.cur_buffer, blank, shift); +} + +/* Scroll up */ +void gray_scroll_up(int count) +{ + unsigned char *data, *data_end; + int length, blank; + + if ((unsigned)count >= (unsigned)_gray_info.height) + return; + + data = _gray_info.cur_buffer; + data_end = data + MULU16(_gray_info.width, _gray_info.height); + length = _gray_info.height - count; + blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + _gray_info.fg_brightness : _gray_info.bg_brightness; + + do + { + my_memmove(data, data + count, length); + _gray_rb->memset(data + length, blank, count); + data += _gray_info.height; + } + while (data < data_end); +} + +/* Scroll down */ +void gray_scroll_down(int count) +{ + unsigned char *data, *data_end; + int length, blank; + + if ((unsigned)count >= (unsigned)_gray_info.height) + return; + + data = _gray_info.cur_buffer; + data_end = data + MULU16(_gray_info.width, _gray_info.height); + length = _gray_info.height - count; + blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ? + _gray_info.fg_brightness : _gray_info.bg_brightness; + + do + { + my_memmove(data + count, data, length); + _gray_rb->memset(data, blank, count); + data += _gray_info.height; + } + while (data < data_end); +} + +/*** Unbuffered scrolling functions ***/ + +/* Scroll left */ +void gray_ub_scroll_left(int count) +{ + int length; + unsigned char *ptr, *ptr_end; + + if ((unsigned) count >= (unsigned) _gray_info.width) + return; + + length = _gray_info.width - count; + ptr = _gray_info.plane_data; + ptr_end = ptr + _gray_info.plane_size; + + /* Scroll row by row to minimize flicker (pixel block rows) */ + do + { + unsigned char *ptr_row = ptr; + unsigned char *row_end = ptr_row + + MULU16(_gray_info.plane_size, _gray_info.depth); + do + { + my_memmove(ptr_row, ptr_row + count, length); + _gray_rb->memset(ptr_row + length, 0, count); + ptr_row += _gray_info.plane_size; + } + while (ptr_row < row_end); + + ptr += _gray_info.width; + } + while (ptr < ptr_end); +} + +/* Scroll right */ +void gray_ub_scroll_right(int count) +{ + int length; + unsigned char *ptr, *ptr_end; + + if ((unsigned) count >= (unsigned) _gray_info.width) + return; + + length = _gray_info.width - count; + ptr = _gray_info.plane_data; + ptr_end = ptr + _gray_info.plane_size; + + /* Scroll row by row to minimize flicker (pixel block rows) */ + do + { + unsigned char *ptr_row = ptr; + unsigned char *row_end = ptr_row + + MULU16(_gray_info.plane_size, _gray_info.depth); + do + { + my_memmove(ptr_row + count, ptr_row, length); + _gray_rb->memset(ptr_row, 0, count); + ptr_row += _gray_info.plane_size; + } + while (ptr_row < row_end); + + ptr += _gray_info.width; + } + while (ptr < ptr_end); +} + +/* Scroll up */ +void gray_ub_scroll_up(int count) +{ + int shift; + long blockshift = 0; + unsigned char *ptr, *ptr_end1, *ptr_end2; + + if ((unsigned) count >= (unsigned) _gray_info.height) + return; + + shift = count >> _PBLOCK_EXP; + count &= (_PBLOCK-1); + + if (shift) + { + blockshift = MULU16(_gray_info.width, shift); + ptr = _gray_info.plane_data; + ptr_end2 = ptr + _gray_info.plane_size; + ptr_end1 = ptr_end2 - blockshift; + /* Scroll row by row to minimize flicker (pixel block rows) */ + do + { + unsigned char *ptr_row = ptr; + unsigned char *row_end = ptr_row + + MULU16(_gray_info.plane_size, _gray_info.depth); + if (ptr < ptr_end1) + { + do + { + _gray_rb->memcpy(ptr_row, ptr_row + blockshift, + _gray_info.width); + ptr_row += _gray_info.plane_size; + } + while (ptr_row < row_end); + } + else + { + do + { + _gray_rb->memset(ptr_row, 0, _gray_info.width); + ptr_row += _gray_info.plane_size; + } + while (ptr_row < row_end); + } + + ptr += _gray_info.width; + } + while (ptr < ptr_end2); + } + if (count) + { +#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) + /* scroll column by column to minimize flicker */ + asm ( + "mov #0,r6 \n" /* x = 0 */ + "mova .su_shifttbl,r0 \n" /* calculate jump destination for */ + "mov.b @(r0,%5),%5 \n" /* shift amount from table */ + "bra .su_cloop \n" /* skip table */ + "add r0,%5 \n" + + ".align 2 \n" + ".su_shifttbl: \n" /* shift jump offset table */ + ".byte .su_shift0 - .su_shifttbl \n" + ".byte .su_shift1 - .su_shifttbl \n" + ".byte .su_shift2 - .su_shifttbl \n" + ".byte .su_shift3 - .su_shifttbl \n" + ".byte .su_shift4 - .su_shifttbl \n" + ".byte .su_shift5 - .su_shifttbl \n" + ".byte .su_shift6 - .su_shifttbl \n" + ".byte .su_shift7 - .su_shifttbl \n" + + ".su_cloop: \n" /* repeat for every column */ + "mov %1,r2 \n" /* get start address */ + "mov #0,r3 \n" /* current_plane = 0 */ + + ".su_oloop: \n" /* repeat for every bitplane */ + "mov r2,r4 \n" /* get start address */ + "mov #0,r5 \n" /* current_row = 0 */ + "mov #0,r1 \n" /* fill with zero */ + + ".su_iloop: \n" /* repeat for all rows */ + "sub %2,r4 \n" /* address -= width */ + "mov.b @r4,r0 \n" /* get data byte */ + "shll8 r1 \n" /* old data to 2nd byte */ + "extu.b r0,r0 \n" /* extend unsigned */ + "or r1,r0 \n" /* combine old data */ + "jmp @%5 \n" /* jump into shift "path" */ + "extu.b r0,r1 \n" /* store data for next round */ + + ".su_shift6: \n" /* shift right by 0..7 bits */ + "shlr2 r0 \n" + ".su_shift4: \n" + "shlr2 r0 \n" + ".su_shift2: \n" + "bra .su_shift0 \n" + "shlr2 r0 \n" + ".su_shift7: \n" + "shlr2 r0 \n" + ".su_shift5: \n" + "shlr2 r0 \n" + ".su_shift3: \n" + "shlr2 r0 \n" + ".su_shift1: \n" + "shlr r0 \n" + ".su_shift0: \n" + + "mov.b r0,@r4 \n" /* store data */ + "add #1,r5 \n" /* current_row++ */ + "cmp/hi r5,%3 \n" /* current_row < bheight - shift ? */ + "bt .su_iloop \n" + + "add %4,r2 \n" /* start_address += plane_size */ + "add #1,r3 \n" /* current_plane++ */ + "cmp/hi r3,%0 \n" /* current_plane < depth ? */ + "bt .su_oloop \n" + + "add #1,%1 \n" /* start_address++ */ + "add #1,r6 \n" /* x++ */ + "cmp/hi r6,%2 \n" /* x < width ? */ + "bt .su_cloop \n" + : /* outputs */ + : /* inputs */ + /* %0 */ "r"(_gray_info.depth), + /* %1 */ "r"(_gray_info.plane_data + _gray_info.plane_size - blockshift), + /* %2 */ "r"(_gray_info.width), + /* %3 */ "r"(_gray_info.bheight - shift), + /* %4 */ "r"(_gray_info.plane_size), + /* %5 */ "r"(count) + : /* clobbers */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6" + ); +#endif + } +} + +/* Scroll down */ +void gray_ub_scroll_down(int count) +{ + int shift; + long blockshift = 0; + unsigned char *ptr, *ptr_end1, *ptr_end2; + + if ((unsigned) count >= (unsigned) _gray_info.height) + return; + + shift = count >> _PBLOCK_EXP; + count &= (_PBLOCK-1); + + if (shift) + { + blockshift = MULU16(_gray_info.width, shift); + ptr_end2 = _gray_info.plane_data; + ptr_end1 = ptr_end2 + blockshift; + ptr = ptr_end2 + _gray_info.plane_size; + /* Scroll row by row to minimize flicker (pixel block rows) */ + do + { + unsigned char *ptr_row, *row_end; + + ptr -= _gray_info.width; + ptr_row = ptr; + row_end = ptr_row + MULU16(_gray_info.plane_size, _gray_info.depth); + + if (ptr >= ptr_end1) + { + do + { + _gray_rb->memcpy(ptr_row, ptr_row - blockshift, + _gray_info.width); + ptr_row += _gray_info.plane_size; + } + while (ptr_row < row_end); + } + else + { + do + { + _gray_rb->memset(ptr_row, 0, _gray_info.width); + ptr_row += _gray_info.plane_size; + } + while (ptr_row < row_end); + } + } + while (ptr > ptr_end2); + } + if (count) + { +#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1) + /* scroll column by column to minimize flicker */ + asm ( + "mov #0,r6 \n" /* x = 0 */ + "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */ + "mov.b @(r0,%5),%5 \n" /* shift amount from table */ + "bra .sd_cloop \n" /* skip table */ + "add r0,%5 \n" + + ".align 2 \n" + ".sd_shifttbl: \n" /* shift jump offset table */ + ".byte .sd_shift0 - .sd_shifttbl \n" + ".byte .sd_shift1 - .sd_shifttbl \n" + ".byte .sd_shift2 - .sd_shifttbl \n" + ".byte .sd_shift3 - .sd_shifttbl \n" + ".byte .sd_shift4 - .sd_shifttbl \n" + ".byte .sd_shift5 - .sd_shifttbl \n" + ".byte .sd_shift6 - .sd_shifttbl \n" + ".byte .sd_shift7 - .sd_shifttbl \n" + + ".sd_cloop: \n" /* repeat for every column */ + "mov %1,r2 \n" /* get start address */ + "mov #0,r3 \n" /* current_plane = 0 */ + + ".sd_oloop: \n" /* repeat for every bitplane */ + "mov r2,r4 \n" /* get start address */ + "mov #0,r5 \n" /* current_row = 0 */ + "mov #0,r1 \n" /* fill with zero */ + + ".sd_iloop: \n" /* repeat for all rows */ + "shlr8 r1 \n" /* shift right to get residue */ + "mov.b @r4,r0 \n" /* get data byte */ + "jmp @%5 \n" /* jump into shift "path" */ + "extu.b r0,r0 \n" /* extend unsigned */ + + ".sd_shift6: \n" /* shift left by 0..7 bits */ + "shll2 r0 \n" + ".sd_shift4: \n" + "shll2 r0 \n" + ".sd_shift2: \n" + "bra .sd_shift0 \n" + "shll2 r0 \n" + ".sd_shift7: \n" + "shll2 r0 \n" + ".sd_shift5: \n" + "shll2 r0 \n" + ".sd_shift3: \n" + "shll2 r0 \n" + ".sd_shift1: \n" + "shll r0 \n" + ".sd_shift0: \n" + + "or r0,r1 \n" /* combine with last residue */ + "mov.b r1,@r4 \n" /* store data */ + "add %2,r4 \n" /* address += width */ + "add #1,r5 \n" /* current_row++ */ + "cmp/hi r5,%3 \n" /* current_row < bheight - shift ? */ + "bt .sd_iloop \n" + + "add %4,r2 \n" /* start_address += plane_size */ + "add #1,r3 \n" /* current_plane++ */ + "cmp/hi r3,%0 \n" /* current_plane < depth ? */ + "bt .sd_oloop \n" + + "add #1,%1 \n" /* start_address++ */ + "add #1,r6 \n" /* x++ */ + "cmp/hi r6,%2 \n" /* x < width ? */ + "bt .sd_cloop \n" + : /* outputs */ + : /* inputs */ + /* %0 */ "r"(_gray_info.depth), + /* %1 */ "r"(_gray_info.plane_data + blockshift), + /* %2 */ "r"(_gray_info.width), + /* %3 */ "r"(_gray_info.bheight - shift), + /* %4 */ "r"(_gray_info.plane_size), + /* %5 */ "r"(count) + : /* clobbers */ + "r0", "r1", "r2", "r3", "r4", "r5", "r6" + ); +#endif + } +} + +#endif /* HAVE_LCD_BITMAP */ +#endif /* !SIMULATOR */ + diff --git a/apps/plugins/lib/gray_scroll_down.c b/apps/plugins/lib/gray_scroll_down.c deleted file mode 100644 index 1fb1de8335..0000000000 --- a/apps/plugins/lib/gray_scroll_down.c +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_scroll_down() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer down by pixels (<= 7) - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the top are black - or white - - Scrolling up/down pixel-wise is significantly slower than scrolling - left/right or scrolling up/down byte-wise because it involves bit - shifting. That's why it is asm optimized. - */ -void gray_scroll_down(int count, bool black_border) -{ - unsigned filler; - - if ((unsigned) count > 7) - return; - - filler = black_border ? (0xFFu << count) : 0; - - /* scroll column by column to minimize flicker */ - asm volatile ( - "mov #0,r6 \n" /* x = 0 */ - "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */ - "mov.b @(r0,%6),%6 \n" /* shift amount from table */ - "bra .sd_cloop \n" /* skip table */ - "add r0,%6 \n" - - ".align 2 \n" - ".sd_shifttbl: \n" /* shift jump offset table */ - ".byte .sd_shift0 - .sd_shifttbl \n" - ".byte .sd_shift1 - .sd_shifttbl \n" - ".byte .sd_shift2 - .sd_shifttbl \n" - ".byte .sd_shift3 - .sd_shifttbl \n" - ".byte .sd_shift4 - .sd_shifttbl \n" - ".byte .sd_shift5 - .sd_shifttbl \n" - ".byte .sd_shift6 - .sd_shifttbl \n" - ".byte .sd_shift7 - .sd_shifttbl \n" - - ".sd_cloop: \n" /* repeat for every column */ - "mov %1,r2 \n" /* get start address */ - "mov #0,r3 \n" /* current_plane = 0 */ - - ".sd_oloop: \n" /* repeat for every bitplane */ - "mov r2,r4 \n" /* get start address */ - "mov #0,r5 \n" /* current_row = 0 */ - "mov %5,r1 \n" /* get filler bits */ - - ".sd_iloop: \n" /* repeat for all rows */ - "shlr8 r1 \n" /* shift right to get residue */ - "mov.b @r4,r0 \n" /* get data byte */ - "jmp @%6 \n" /* jump into shift "path" */ - "extu.b r0,r0 \n" /* extend unsigned */ - - ".sd_shift6: \n" /* shift left by 0..7 bits */ - "shll2 r0 \n" - ".sd_shift4: \n" - "shll2 r0 \n" - ".sd_shift2: \n" - "bra .sd_shift0 \n" - "shll2 r0 \n" - ".sd_shift7: \n" - "shll2 r0 \n" - ".sd_shift5: \n" - "shll2 r0 \n" - ".sd_shift3: \n" - "shll2 r0 \n" - ".sd_shift1: \n" - "shll r0 \n" - ".sd_shift0: \n" - - "or r0,r1 \n" /* combine with last residue */ - "mov.b r1,@r4 \n" /* store data */ - "add %2,r4 \n" /* address += width */ - "add #1,r5 \n" /* current_row++ */ - "cmp/hi r5,%3 \n" /* current_row < bheight ? */ - "bt .sd_iloop \n" - - "add %4,r2 \n" /* start_address += plane_size */ - "add #1,r3 \n" /* current_plane++ */ - "cmp/hi r3,%0 \n" /* current_plane < depth ? */ - "bt .sd_oloop \n" - - "add #1,%1 \n" /* start_address++ */ - "add #1,r6 \n" /* x++ */ - "cmp/hi r6,%2 \n" /* x < width ? */ - "bt .sd_cloop \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(_graybuf->depth), - /* %1 */ "r"(_graybuf->data), - /* %2 */ "r"(_graybuf->width), - /* %3 */ "r"(_graybuf->bheight), - /* %4 */ "r"(_graybuf->plane_size), - /* %5 */ "r"(filler), - /* %6 */ "r"(count) - : /* clobbers */ - "r0", "r1", "r2", "r3", "r4", "r5", "r6" - ); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_scroll_down8.c b/apps/plugins/lib/gray_scroll_down8.c deleted file mode 100644 index db716baee7..0000000000 --- a/apps/plugins/lib/gray_scroll_down8.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_scroll_down8() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer down by 8 pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the top are black - or white - - Scrolling up/down by 8 pixels is very fast. - */ -void gray_scroll_down8(bool black_border) -{ - int by, d; - unsigned filler; - unsigned char *ptr; - - filler = black_border ? 0xFF : 0; - - /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */ - for (by = _graybuf->bheight - 1; by > 0; by--) - { - ptr = _graybuf->data + MULU16(_graybuf->width, by); - for (d = 0; d < _graybuf->depth; d++) - { - _gray_rb->memcpy(ptr, ptr - _graybuf->width, _graybuf->width); - ptr += _graybuf->plane_size; - } - } - /* fill first row */ - ptr = _graybuf->data; - for (d = 0; d < _graybuf->depth; d++) - { - _gray_rb->memset(ptr, filler, _graybuf->width); - ptr += _graybuf->plane_size; - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_scroll_left.c b/apps/plugins/lib/gray_scroll_left.c deleted file mode 100644 index 5fb9a441c1..0000000000 --- a/apps/plugins/lib/gray_scroll_left.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_scroll_left() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer left by pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the right are black - or white - - Scrolling left/right by an even pixel count is almost twice as fast as - scrolling by an odd pixel count. - */ -void gray_scroll_left(int count, bool black_border) -{ - int by, d; - unsigned filler; - unsigned char *ptr; - - if ((unsigned) count >= (unsigned) _graybuf->width) - return; - - filler = black_border ? 0xFF : 0; - - /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */ - for (by = 0; by < _graybuf->bheight; by++) - { - ptr = _graybuf->data + MULU16(_graybuf->width, by); - for (d = 0; d < _graybuf->depth; d++) - { - asm volatile ( - "mov %0,r1 \n" /* check if both source... */ - "or %2,r1 \n" /* ...and offset are even */ - "shlr r1 \n" /* -> lsb = 0 */ - "bf .sl_start2 \n" /* -> copy word-wise */ - - "add #-1,%2 \n" /* copy byte-wise */ - ".sl_loop1: \n" - "mov.b @%0+,r1 \n" - "mov.b r1,@(%2,%0) \n" - "cmp/hi %0,%1 \n" - "bt .sl_loop1 \n" - - "bra .sl_end \n" - "nop \n" - - ".sl_start2: \n" /* copy word-wise */ - "add #-2,%2 \n" - ".sl_loop2: \n" - "mov.w @%0+,r1 \n" - "mov.w r1,@(%2,%0) \n" - "cmp/hi %0,%1 \n" - "bt .sl_loop2 \n" - - ".sl_end: \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(ptr + count), - /* %1 */ "r"(ptr + _graybuf->width), - /* %2 */ "z"(-count) - : /* clobbers */ - "r1" - ); - - _gray_rb->memset(ptr + _graybuf->width - count, filler, count); - ptr += _graybuf->plane_size; - } - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_scroll_right.c b/apps/plugins/lib/gray_scroll_right.c deleted file mode 100644 index f944319d91..0000000000 --- a/apps/plugins/lib/gray_scroll_right.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_scroll_right() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer right by pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the left are black - or white - - Scrolling left/right by an even pixel count is almost twice as fast as - scrolling by an odd pixel count. - */ -void gray_scroll_right(int count, bool black_border) -{ - int by, d; - unsigned filler; - unsigned char *ptr; - - if ((unsigned) count >= (unsigned) _graybuf->width) - return; - - filler = black_border ? 0xFF : 0; - - /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */ - for (by = 0; by < _graybuf->bheight; by++) - { - ptr = _graybuf->data + MULU16(_graybuf->width, by); - for (d = 0; d < _graybuf->depth; d++) - { - asm volatile ( - "mov %0,r1 \n" /* check if both source... */ - "or %2,r1 \n" /* ...and offset are even */ - "shlr r1 \n" /* -> lsb = 0 */ - "bf .sr_start2 \n" /* -> copy word-wise */ - - "add #-1,%2 \n" /* copy byte-wise */ - ".sr_loop1: \n" - "mov.b @(%2,%0),r1 \n" - "mov.b r1,@-%0 \n" - "cmp/hi %1,%0 \n" - "bt .sr_loop1 \n" - - "bra .sr_end \n" - "nop \n" - - ".sr_start2: \n" /* copy word-wise */ - "add #-2,%2 \n" - ".sr_loop2: \n" - "mov.w @(%2,%0),r1 \n" - "mov.w r1,@-%0 \n" - "cmp/hi %1,%0 \n" - "bt .sr_loop2 \n" - - ".sr_end: \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(ptr + _graybuf->width), - /* %1 */ "r"(ptr + count), - /* %2 */ "z"(-count) - : /* clobbers */ - "r1" - ); - - _gray_rb->memset(ptr, filler, count); - ptr += _graybuf->plane_size; - } - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_scroll_up.c b/apps/plugins/lib/gray_scroll_up.c deleted file mode 100644 index 4c493071af..0000000000 --- a/apps/plugins/lib/gray_scroll_up.c +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_scroll_up() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer up by pixels (<= 7) - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the bottom are black - or white - - Scrolling up/down pixel-wise is significantly slower than scrolling - left/right or scrolling up/down byte-wise because it involves bit - shifting. That's why it is asm optimized. - */ -void gray_scroll_up(int count, bool black_border) -{ - unsigned filler; - - if ((unsigned) count > 7) - return; - - filler = black_border ? 0xFFu : 0; - - /* scroll column by column to minimize flicker */ - asm volatile ( - "mov #0,r6 \n" /* x = 0 */ - "mova .su_shifttbl,r0 \n" /* calculate jump destination for */ - "mov.b @(r0,%6),%6 \n" /* shift amount from table */ - "bra .su_cloop \n" /* skip table */ - "add r0,%6 \n" - - ".align 2 \n" - ".su_shifttbl: \n" /* shift jump offset table */ - ".byte .su_shift0 - .su_shifttbl \n" - ".byte .su_shift1 - .su_shifttbl \n" - ".byte .su_shift2 - .su_shifttbl \n" - ".byte .su_shift3 - .su_shifttbl \n" - ".byte .su_shift4 - .su_shifttbl \n" - ".byte .su_shift5 - .su_shifttbl \n" - ".byte .su_shift6 - .su_shifttbl \n" - ".byte .su_shift7 - .su_shifttbl \n" - - ".su_cloop: \n" /* repeat for every column */ - "mov %1,r2 \n" /* get start address */ - "mov #0,r3 \n" /* current_plane = 0 */ - - ".su_oloop: \n" /* repeat for every bitplane */ - "mov r2,r4 \n" /* get start address */ - "mov #0,r5 \n" /* current_row = 0 */ - "mov %5,r1 \n" /* get filler bits */ - - ".su_iloop: \n" /* repeat for all rows */ - "sub %2,r4 \n" /* address -= width */ - "mov.b @r4,r0 \n" /* get data byte */ - "shll8 r1 \n" /* old data to 2nd byte */ - "extu.b r0,r0 \n" /* extend unsigned */ - "or r1,r0 \n" /* combine old data */ - "jmp @%6 \n" /* jump into shift "path" */ - "extu.b r0,r1 \n" /* store data for next round */ - - ".su_shift6: \n" /* shift right by 0..7 bits */ - "shlr2 r0 \n" - ".su_shift4: \n" - "shlr2 r0 \n" - ".su_shift2: \n" - "bra .su_shift0 \n" - "shlr2 r0 \n" - ".su_shift7: \n" - "shlr2 r0 \n" - ".su_shift5: \n" - "shlr2 r0 \n" - ".su_shift3: \n" - "shlr2 r0 \n" - ".su_shift1: \n" - "shlr r0 \n" - ".su_shift0: \n" - - "mov.b r0,@r4 \n" /* store data */ - "add #1,r5 \n" /* current_row++ */ - "cmp/hi r5,%3 \n" /* current_row < bheight ? */ - "bt .su_iloop \n" - - "add %4,r2 \n" /* start_address += plane_size */ - "add #1,r3 \n" /* current_plane++ */ - "cmp/hi r3,%0 \n" /* current_plane < depth ? */ - "bt .su_oloop \n" - - "add #1,%1 \n" /* start_address++ */ - "add #1,r6 \n" /* x++ */ - "cmp/hi r6,%2 \n" /* x < width ? */ - "bt .su_cloop \n" - : /* outputs */ - : /* inputs */ - /* %0 */ "r"(_graybuf->depth), - /* %1 */ "r"(_graybuf->data + _graybuf->plane_size), - /* %2 */ "r"(_graybuf->width), - /* %3 */ "r"(_graybuf->bheight), - /* %4 */ "r"(_graybuf->plane_size), - /* %5 */ "r"(filler), - /* %6 */ "r"(count) - : /* clobbers */ - "r0", "r1", "r2", "r3", "r4", "r5", "r6" - ); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_scroll_up8.c b/apps/plugins/lib/gray_scroll_up8.c deleted file mode 100644 index b181673f22..0000000000 --- a/apps/plugins/lib/gray_scroll_up8.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_scroll_up8() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Scroll the whole grayscale buffer up by 8 pixels - ---------------------------------------------------------------------------- - black_border determines if the pixels scrolled in at the bottom are black - or white - - Scrolling up/down by 8 pixels is very fast. - */ -void gray_scroll_up8(bool black_border) -{ - int by, d; - unsigned filler; - unsigned char *ptr; - - filler = black_border ? 0xFF : 0; - - /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */ - for (by = 1; by < _graybuf->bheight; by++) - { - ptr = _graybuf->data + MULU16(_graybuf->width, by); - for (d = 0; d < _graybuf->depth; d++) - { - _gray_rb->memcpy(ptr - _graybuf->width, ptr, _graybuf->width); - ptr += _graybuf->plane_size; - } - } - /* fill last row */ - ptr = _graybuf->data + _graybuf->plane_size - _graybuf->width; - for (d = 0; d < _graybuf->depth; d++) - { - _gray_rb->memset(ptr, filler, _graybuf->width); - ptr += _graybuf->plane_size; - } -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_set_background.c b/apps/plugins/lib/gray_set_background.c deleted file mode 100644 index c78e9ff112..0000000000 --- a/apps/plugins/lib/gray_set_background.c +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_set_background() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set the background shade for subsequent drawing operations - ---------------------------------------------------------------------------- - brightness = 0 (black) .. 255 (white) - - Default after initialization: 255 - */ -void gray_set_background(int brightness) -{ - if ((unsigned) brightness <= 255) - _graybuf->bg_pattern = _graybuf->bitpattern[MULU16(brightness, - _graybuf->depth + 1) >> 8]; -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_set_drawinfo.c b/apps/plugins/lib/gray_set_drawinfo.c deleted file mode 100644 index 59928882d7..0000000000 --- a/apps/plugins/lib/gray_set_drawinfo.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_set_drawinfo() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set draw mode, foreground and background shades at once - ---------------------------------------------------------------------------- - If you hand it -1 (or in fact any other out-of-bounds value) for a - parameter, that particular setting won't be changed - - Default after initialization: GRAY_DRAW_SOLID, 0, 255 - */ -void gray_set_drawinfo(int drawmode, int fg_brightness, int bg_brightness) -{ - gray_set_drawmode(drawmode); - gray_set_foreground(fg_brightness); - gray_set_background(bg_brightness); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_set_drawmode.c b/apps/plugins/lib/gray_set_drawmode.c deleted file mode 100644 index 969b99894f..0000000000 --- a/apps/plugins/lib/gray_set_drawmode.c +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_set_drawmode() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set the draw mode for subsequent drawing operations - ---------------------------------------------------------------------------- - drawmode = - GRAY_DRAW_INVERSE: Foreground pixels are inverted, background pixels are - left untouched - GRAY_DRAW_FG: Only foreground pixels are drawn - GRAY_DRAW_BG: Only background pixels are drawn - GRAY_DRAW_SOLID: Foreground and background pixels are drawn - - Default after initialization: GRAY_DRAW_SOLID - */ -void gray_set_drawmode(int drawmode) -{ - if ((unsigned) drawmode <= GRAY_DRAW_SOLID) - _graybuf->drawmode = drawmode; -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_set_foreground.c b/apps/plugins/lib/gray_set_foreground.c deleted file mode 100644 index afde64f645..0000000000 --- a/apps/plugins/lib/gray_set_foreground.c +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_set_foreground() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set the foreground shade for subsequent drawing operations - ---------------------------------------------------------------------------- - brightness = 0 (black) .. 255 (white) - - Default after initialization: 0 - */ -void gray_set_foreground(int brightness) -{ - if ((unsigned) brightness <= 255) - _graybuf->fg_pattern = _graybuf->bitpattern[MULU16(brightness, - _graybuf->depth + 1) >> 8]; -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_setfont.c b/apps/plugins/lib/gray_setfont.c deleted file mode 100644 index 714a1f5b17..0000000000 --- a/apps/plugins/lib/gray_setfont.c +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* gray_setfont() function -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Set font for the font routines - ---------------------------------------------------------------------------- - newfont can be FONT_SYSFIXED or FONT_UI the same way as with the Rockbox - core routines - - Default after initialization: FONT_SYSFIXED - */ -void gray_setfont(int newfont) -{ - _graybuf->curfont = _gray_rb->font_get(newfont); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/lib/gray_verline.c b/apps/plugins/lib/gray_verline.c deleted file mode 100644 index 15910b41cf..0000000000 --- a/apps/plugins/lib/gray_verline.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************** -* __________ __ ___. -* Open \______ \ ____ ____ | | _\_ |__ _______ ___ -* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / -* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < -* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ -* \/ \/ \/ \/ \/ -* $Id$ -* -* Grayscale framework -* gray_verline() function -* -* This is a generic framework to use grayscale display within Rockbox -* plugins. It obviously does not work for the player. -* -* Copyright (C) 2004 Jens Arnold -* -* All files in this archive are subject to the GNU General Public License. -* See the file COPYING in the source tree root for full license agreement. -* -* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -* KIND, either express or implied. -* -****************************************************************************/ - -#ifndef SIMULATOR /* not for simulator by now */ -#include "plugin.h" - -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ -#include "gray.h" - -/*--------------------------------------------------------------------------- - Draw a vertical line from (x, y1) to (x, y2) with the current drawinfo - ---------------------------------------------------------------------------- - See gray_drawpixel() for details - This one uses the block drawing optimization, so it is rather fast. - */ -void gray_verline(int x, int y1, int y2) -{ - int shift, y, ny; - unsigned bits, mask_top, mask_bottom; - unsigned char *dst; - void (*blockfunc)(unsigned char *address, unsigned mask, unsigned bits); - - if ((unsigned) x >= (unsigned) _graybuf->width - || (unsigned) y1 >= (unsigned) _graybuf->height - || (unsigned) y2 >= (unsigned) _graybuf->height) - return; - - if (y1 > y2) - { - y = y1; - y1 = y2; - y2 = y; - } - y = y1; - ny = y2 - y1 + 1; - - dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3); - shift = y & 7; - ny += shift; - - mask_top = 0xFFu << (y & 7); - mask_bottom = ~(0xFEu << ((ny - 1) & 7)); - if (ny <= 8) - mask_bottom &= mask_top; - - blockfunc = _gray_blockfuncs[_graybuf->drawmode]; - bits = (_graybuf->drawmode == GRAY_DRAW_BG) ? 0u : 0xFFu; - - if (ny > 8) - { - blockfunc(dst, mask_top, bits); - dst += _graybuf->width; - - for (y = 8; y < ny - 8; y += 8) - { - blockfunc(dst, 0xFFu, bits); - dst += _graybuf->width; - } - } - - blockfunc(dst, mask_bottom, bits); -} - -#endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR - diff --git a/apps/plugins/mandelbrot.c b/apps/plugins/mandelbrot.c index bb96b9b71c..1037212b15 100644 --- a/apps/plugins/mandelbrot.c +++ b/apps/plugins/mandelbrot.c @@ -94,7 +94,7 @@ void calc_mandelbrot_set(void){ start_tick = last_yield = *rb->current_tick; - gray_clear_display(); + gray_ub_clear_display(); x_fact = (x_max - x_min) / LCD_WIDTH; y_fact = (y_max - y_min) / LCD_HEIGHT; @@ -124,7 +124,7 @@ void calc_mandelbrot_set(void){ if (n_iter > max_iter){ brightness = 0; // black } else { - brightness = 255 - (31 * (n_iter & 7)); + brightness = 255 - (32 * (n_iter & 7)); } graybuffer[y_pixel]=brightness; /* be nice to other threads: @@ -134,7 +134,7 @@ void calc_mandelbrot_set(void){ last_yield = *rb->current_tick; } } - gray_drawgraymap(graybuffer, x_pixel, 0, 1, LCD_HEIGHT, 1); + gray_ub_gray_bitmap(graybuffer, x_pixel, 0, 1, LCD_HEIGHT); } } @@ -142,7 +142,7 @@ void cleanup(void *parameter) { (void)parameter; - gray_release_buffer(); + gray_release(); } enum plugin_status plugin_start(struct plugin_api* api, void* parameter) @@ -156,17 +156,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb = api; (void)parameter; - /* This plugin uses the grayscale framework, so initialize */ - gray_init(api); - /* get the remainder of the plugin buffer */ gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); /* initialize the grayscale buffer: * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve * 16 bitplanes for 17 shades of gray.*/ - grayscales = gray_init_buffer(gbuf, gbuf_size, 112, 8, 16, NULL) + 1; - if (grayscales != 17){ + grayscales = gray_init(rb, gbuf, gbuf_size, false, 112, 8, 8, NULL) + 1; + if (grayscales != 9){ rb->snprintf(buff, sizeof(buff), "%d", grayscales); rb->lcd_puts(0, 1, buff); rb->lcd_update(); @@ -174,7 +171,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) return(0); } - gray_show_display(true); /* switch on grayscale overlay */ + gray_show(true); /* switch on greyscale overlay */ init_mandelbrot_set(); lcd_aspect_ratio = ((LCD_WIDTH<<13) / LCD_HEIGHT)<<13; @@ -189,7 +186,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) button = rb->button_get(true); switch (button) { case MANDELBROT_QUIT: - gray_release_buffer(); + gray_release(); return PLUGIN_OK; case MANDELBROT_ZOOM_OUT: @@ -270,7 +267,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) if (button != BUTTON_NONE) lastbutton = button; } - gray_release_buffer(); + gray_release(); return PLUGIN_OK; } #endif