diff options
-rw-r--r-- | apps/plugin.c | 6 | ||||
-rw-r--r-- | apps/plugin.h | 6 | ||||
-rw-r--r-- | apps/plugins/brickmania.c | 1 | ||||
-rw-r--r-- | apps/plugins/cube.c | 2 | ||||
-rw-r--r-- | apps/plugins/fire.c | 2 | ||||
-rw-r--r-- | apps/plugins/grayscale.c | 2 | ||||
-rw-r--r-- | apps/plugins/jpeg.c | 4 | ||||
-rw-r--r-- | apps/plugins/lib/SOURCES | 3 | ||||
-rw-r--r-- | apps/plugins/lib/gray.h | 18 | ||||
-rw-r--r-- | apps/plugins/lib/gray_core.c | 206 | ||||
-rw-r--r-- | apps/plugins/lib/gray_draw.c | 32 | ||||
-rw-r--r-- | apps/plugins/lib/gray_parm.c | 18 | ||||
-rw-r--r-- | apps/plugins/lib/gray_scroll.c | 43 | ||||
-rw-r--r-- | apps/plugins/mandelbrot.c | 2 | ||||
-rw-r--r-- | apps/plugins/plasma.c | 4 | ||||
-rw-r--r-- | uisimulator/sdl/lcd-bitmap.c | 89 | ||||
-rw-r--r-- | uisimulator/sdl/lcd-bitmap.h | 4 | ||||
-rw-r--r-- | uisimulator/sdl/lcd-charcell.c | 9 | ||||
-rw-r--r-- | uisimulator/sdl/lcd-remote.c | 19 | ||||
-rw-r--r-- | uisimulator/sdl/lcd-sdl.c | 36 | ||||
-rw-r--r-- | uisimulator/sdl/lcd-sdl.h | 9 |
21 files changed, 383 insertions, 132 deletions
diff --git a/apps/plugin.c b/apps/plugin.c index 61396b4357..2bf6aa772d 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -72,6 +72,8 @@ static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE]; void *sim_plugin_load(char *plugin, int *fd); void sim_plugin_close(int fd); +void sim_lcd_ex_init(int shades, unsigned long (*getpixel)(int, int)); +void sim_lcd_ex_update_rect(int x, int y, int width, int height); #else #define sim_plugin_close(x) extern unsigned char pluginbuf[]; @@ -401,6 +403,10 @@ static const struct plugin_api rockbox_api = { /* new stuff at the end, sort into place next time the API gets incompatible */ tree_get_context, +#if defined(SIMULATOR) && defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8 + sim_lcd_ex_init, + sim_lcd_ex_update_rect, +#endif }; int plugin_load(const char* plugin, void* parameter) diff --git a/apps/plugin.h b/apps/plugin.h index 7c35902248..6d96d36dc1 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -98,7 +98,7 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 8 +#define PLUGIN_API_VERSION 9 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -469,6 +469,10 @@ struct plugin_api { the API gets incompatible */ struct tree_context* (*tree_get_context)(void); +#if defined(SIMULATOR) && defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8 + void (*sim_lcd_ex_init)(int shades, unsigned long (*getpixel)(int, int)); + void (*sim_lcd_ex_update_rect)(int x, int y, int width, int height); +#endif }; diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c index a21ba7ae5c..2b2671d6be 100644 --- a/apps/plugins/brickmania.c +++ b/apps/plugins/brickmania.c @@ -18,7 +18,6 @@ ****************************************************************************/ #include "plugin.h" -#include "gray.h" #include "configfile.h" /* Part of libplugin */ PLUGIN_HEADER diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c index cbe32d14d0..854b190797 100644 --- a/apps/plugins/cube.c +++ b/apps/plugins/cube.c @@ -142,7 +142,7 @@ PLUGIN_HEADER static int x_off = LCD_WIDTH/2; static int y_off = LCD_HEIGHT/2; -#if LCD_DEPTH == 1 && !defined(SIMULATOR) +#if LCD_DEPTH == 1 #define USE_GSLIB struct my_lcd { void (*update)(void); diff --git a/apps/plugins/fire.c b/apps/plugins/fire.c index 859ba598b2..5bcf909108 100644 --- a/apps/plugins/fire.c +++ b/apps/plugins/fire.c @@ -19,7 +19,6 @@ * ****************************************************************************/ -#ifndef SIMULATOR /* not for simulator (grayscale) */ #include "plugin.h" #ifdef HAVE_LCD_BITMAP /* and also not for the Player */ @@ -305,4 +304,3 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) } #endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR diff --git a/apps/plugins/grayscale.c b/apps/plugins/grayscale.c index ff94e6ae8c..4ca2ba09b3 100644 --- a/apps/plugins/grayscale.c +++ b/apps/plugins/grayscale.c @@ -19,7 +19,6 @@ * ****************************************************************************/ -#ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && (CONFIG_LCD != LCD_IPOD2BPP) @@ -336,5 +335,4 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) } #endif // #ifdef HAVE_LCD_BITMAP -#endif // #ifndef SIMULATOR diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c index ce27d7da3f..a39e6dc933 100644 --- a/apps/plugins/jpeg.c +++ b/apps/plugins/jpeg.c @@ -26,7 +26,7 @@ #include "plugin.h" -#if defined(HAVE_LCD_BITMAP) && ((LCD_DEPTH >= 8) || !defined(SIMULATOR)) +#ifdef HAVE_LCD_BITMAP #include "gray.h" #include "xlcd.h" @@ -2713,4 +2713,4 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) return condition; } -#endif /* HAVE_LCD_BITMAP && ((LCD_DEPTH >= 8) || !defined(SIMULATOR))*/ +#endif /* HAVE_LCD_BITMAP */ diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 291bc21a1d..6bcddbab96 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -1,6 +1,5 @@ configfile.c -#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && !defined(SIMULATOR) && \ - (CONFIG_LCD != LCD_IPOD2BPP) +#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) && (CONFIG_LCD != LCD_IPOD2BPP) gray_core.c gray_draw.c gray_parm.c diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h index 7092b84958..96dec346cf 100644 --- a/apps/plugins/lib/gray.h +++ b/apps/plugins/lib/gray.h @@ -9,10 +9,10 @@ * * Greyscale framework * -* This is a generic framework to use greyscale display within Rockbox -* plugins. It does not work for the player. +* This is a generic framework to display up to 33 shades of grey +* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. * -* Copyright (C) 2004-2005 Jens Arnold +* Copyright (C) 2004-2006 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. @@ -25,7 +25,6 @@ #ifndef __GRAY_H__ #define __GRAY_H__ -#ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" #ifdef HAVE_LCD_BITMAP /* and also not for the Player */ @@ -129,17 +128,19 @@ struct _gray_info int height; int bheight; /* 8-pixel units */ int depth; /* number_of_bitplanes = (number_of_grayscales - 1) */ + unsigned long flags; /* various flags, see #defines */ +#ifndef SIMULATOR int cur_plane; /* for the timer isr */ - int drawmode; /* current draw mode */ - 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 */ +#endif unsigned char *cur_buffer; /* start of current chunky pixel buffer */ unsigned char *back_buffer;/* start of chunky pixel back buffer */ + int drawmode; /* current draw mode */ + int fg_brightness; /* current foreground brightness */ + int bg_brightness; /* current background brightness */ int curfont; /* current selected font */ }; @@ -149,5 +150,4 @@ extern struct _gray_info _gray_info; extern short _gray_random_buffer; #endif /* HAVE_LCD_BITMAP */ -#endif /* !SIMULATOR */ #endif /* __GRAY_H__ */ diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c index d151250e69..80ce984b29 100644 --- a/apps/plugins/lib/gray_core.c +++ b/apps/plugins/lib/gray_core.c @@ -10,10 +10,10 @@ * 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. +* This is a generic framework to display up to 33 shades of grey +* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. * -* Copyright (C) 2004-2005 Jens Arnold +* Copyright (C) 2004-2006 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. @@ -23,21 +23,49 @@ * ****************************************************************************/ -#ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#ifdef HAVE_LCD_BITMAP #include "gray.h" /* Global variables */ struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ struct _gray_info _gray_info; /* global info structure */ +#ifndef SIMULATOR short _gray_random_buffer; /* buffer for random number generator */ +#endif /* Prototypes */ +static inline void _deferred_update(void) __attribute__ ((always_inline)); +#ifdef SIMULATOR +static unsigned long _gray_get_pixel(int x, int y); +#else static void _timer_isr(void); +#endif static void gray_screendump_hook(int fd); +/* Update LCD areas not covered by the greyscale overlay */ +static inline void _deferred_update(void) +{ + 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); + + if (y2 < LCD_HEIGHT) /* refresh part below overlay, full width */ + _gray_rb->lcd_update_rect(0, y2, LCD_WIDTH, LCD_HEIGHT - y2); + + if (x1 > 0) /* refresh part to the left of overlay */ + _gray_rb->lcd_update_rect(0, y1, x1, y2 - y1); + + if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */ + _gray_rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1); +} + +#ifndef SIMULATOR /* Timer interrupt handler: display next bitplane */ static void _timer_isr(void) { @@ -50,26 +78,11 @@ static void _timer_isr(void) if (_gray_info.flags & _GRAY_DEFERRED_UPDATE) /* lcd_update() requested? */ { - 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); - - if (y2 < LCD_HEIGHT) /* refresh part below overlay, full width */ - _gray_rb->lcd_update_rect(0, y2, LCD_WIDTH, LCD_HEIGHT - y2); - - if (x1 > 0) /* refresh part to the left of overlay */ - _gray_rb->lcd_update_rect(0, y1, x1, y2 - y1); - - if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */ - _gray_rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1); - + _deferred_update(); _gray_info.flags &= ~_GRAY_DEFERRED_UPDATE; /* clear request */ } } +#endif /* !SIMULATOR */ /* Initialise the framework and prepare the greyscale display buffer @@ -108,13 +121,21 @@ static void _timer_isr(void) + (width * bheight) * depth (bitplane data) + buffered ? (chunky front- & backbuffer) (width * bheight * 8 * 2) : 0 - + 0..3 (longword alignment) */ + + 0..3 (longword alignment) + + The function tries to be as authentic as possible regarding memory usage on + the simulator, even if it doesn't use all of the allocated memory. There's + one situation where it will consume more memory on the sim than on the + target: if you're allocating a low depth (< 8) without buffering. */ 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, i, j; + int possible_depth; long plane_size, buftaken; - +#ifndef SIMULATOR + int i, j; +#endif + _gray_rb = newrb; if ((unsigned) width > LCD_WIDTH @@ -152,19 +173,41 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, depth = MIN(depth, 32); depth = MIN(depth, possible_depth); +#ifdef SIMULATOR + if (!buffered) + { + long orig_size = depth * plane_size + (depth + 1) * sizeof(long); + + plane_size = MULU16(width, bheight << _PBLOCK_EXP); + if (plane_size > orig_size) + { + buftaken += plane_size; + if (buftaken > gbuf_size) + return 0; + } + else + { + buftaken += orig_size; + } + _gray_info.cur_buffer = gbuf; + } + else +#endif + buftaken += depth * plane_size + (depth + 1) * sizeof(long); + _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; +#ifndef SIMULATOR + _gray_info.cur_plane = 0; + _gray_info.plane_size = plane_size; _gray_info.plane_data = gbuf; gbuf += depth * plane_size; _gray_info.bitpattern = (unsigned long *)gbuf; - buftaken += depth * plane_size + (depth + 1) * sizeof(long); i = depth - 1; j = 8; @@ -195,6 +238,7 @@ int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, _gray_info.bitpattern[i] = pattern; } +#endif _gray_info.fg_brightness = 0; _gray_info.bg_brightness = depth; @@ -229,6 +273,10 @@ void gray_show(bool enable) if (enable && !(_gray_info.flags & _GRAY_RUNNING)) { _gray_info.flags |= _GRAY_RUNNING; +#ifdef SIMULATOR + _gray_rb->sim_lcd_ex_init(_gray_info.depth + 1, _gray_get_pixel); + gray_update(); +#else /* !SIMULATOR */ #if CONFIG_LCD == LCD_SSD1815 _gray_rb->timer_register(1, NULL, CPU_FREQ / 67, 1, _timer_isr); #elif CONFIG_LCD == LCD_S1D15E06 @@ -236,18 +284,53 @@ void gray_show(bool enable) #elif CONFIG_LCD == LCD_IFP7XX /* TODO: implement for iFP */ (void)_timer_isr; -#endif +#endif /* CONFIG_LCD */ +#endif /* !SIMULATOR */ _gray_rb->screen_dump_set_hook(gray_screendump_hook); } else if (!enable && (_gray_info.flags & _GRAY_RUNNING)) { +#ifdef SIMULATOR + _gray_rb->sim_lcd_ex_init(0, NULL); +#else _gray_rb->timer_unregister(); +#endif _gray_info.flags &= ~_GRAY_RUNNING; _gray_rb->screen_dump_set_hook(NULL); _gray_rb->lcd_update(); /* restore whatever there was before */ } } +#ifdef SIMULATOR +/* Callback function for gray_update_rect() to read a pixel from the graybuffer. + Note that x and y are in LCD coordinates, not graybuffer coordinates! */ +static unsigned long _gray_get_pixel(int x, int y) +{ + return _gray_info.cur_buffer[MULU16(x - _gray_info.x, _gray_info.height) + + y - (_gray_info.by << _PBLOCK_EXP)] + + (1 << LCD_DEPTH); +} + +/* Update a rectangular area of the greyscale overlay */ +void gray_update_rect(int x, int y, int width, int height) +{ + if (x + width > _gray_info.width) + width = _gray_info.width - x; + if (y + height > _gray_info.height) + height = _gray_info.height - y; + + x += _gray_info.x; + y += _gray_info.by << _PBLOCK_EXP; + + if (x + width > LCD_WIDTH) + width = LCD_WIDTH - x; + if (y + height > LCD_HEIGHT) + height = LCD_HEIGHT - y; + + _gray_rb->sim_lcd_ex_update_rect(x, y, width, height); +} + +#else /* !SIMULATOR */ /* Update a rectangular area of the greyscale overlay */ void gray_update_rect(int x, int y, int width, int height) { @@ -647,7 +730,7 @@ void gray_update_rect(int x, int y, int width, int height) "d0", "d1", "d2", "d3", "d4", "d5", "d6", "a0", "a1" ); } -#endif +#endif /* CONFIG_CPU, LCD_DEPTH */ srcofs_row += _gray_info.height; dst_row++; } @@ -657,7 +740,6 @@ void gray_update_rect(int x, int y, int width, int height) dst += _gray_info.width; } } - #if CONFIG_CPU == SH7034 /* References to C library routines used in gray_update_rect() */ asm ( @@ -668,7 +750,9 @@ asm ( ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */ /* both routines preserve r4, destroy r5 and take ~16 cycles */ ); -#endif +#endif /* CONFIG_CPU == SH7034 */ + +#endif /* !SIMULATOR */ /* Update the whole greyscale overlay */ void gray_update(void) @@ -681,7 +765,13 @@ void gray_update(void) void gray_deferred_lcd_update(void) { if (_gray_info.flags & _GRAY_RUNNING) + { +#ifdef SIMULATOR + _deferred_update(); +#else _gray_info.flags |= _GRAY_DEFERRED_UPDATE; +#endif + } else _gray_rb->lcd_update(); } @@ -745,17 +835,14 @@ static const unsigned char bmpheader[] = content (b&w and greyscale overlay) to an 8-bit BMP file. */ static void gray_screendump_hook(int fd) { - int i, idx; + int i; int x, y, by; - int gx, mask; -#if LCD_DEPTH == 1 - int gby; -#elif LCD_DEPTH == 2 - int shift, gy; + int gx, gy, mask; +#if LCD_DEPTH == 2 + int shift; #endif unsigned char *clut_entry; unsigned char *lcdptr; - unsigned char *grayptr, *grayptr2; unsigned char linebuf[MAX(4*BMP_VARCOLORS,BMP_LINESIZE)]; _gray_rb->write(fd, bmpheader, sizeof(bmpheader)); /* write header */ @@ -778,16 +865,19 @@ static void gray_screendump_hook(int fd) { _gray_rb->memset(linebuf, 0, BMP_LINESIZE); + gy = y - (_gray_info.by << _PBLOCK_EXP); #if LCD_DEPTH == 1 mask = 1 << (y & (_PBLOCK-1)); by = y >> _PBLOCK_EXP; lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); - gby = by - _gray_info.by; - if ((unsigned) gby < (unsigned) _gray_info.bheight) + if ((unsigned) gy < (unsigned) _gray_info.height) { /* line contains greyscale (and maybe b&w) graphics */ - grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby); +#ifndef SIMULATOR + unsigned char *grayptr = _gray_info.plane_data + + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); +#endif for (x = 0; x < LCD_WIDTH; x++) { @@ -795,8 +885,12 @@ static void gray_screendump_hook(int fd) if ((unsigned)gx < (unsigned)_gray_info.width) { - idx = BMP_FIXEDCOLORS; - grayptr2 = grayptr + gx; +#ifdef SIMULATOR + linebuf[x] = BMP_FIXEDCOLORS + _gray_info.depth + - _gray_info.cur_buffer[MULU16(gx, _gray_info.height) + gy]; +#else + int idx = BMP_FIXEDCOLORS; + unsigned char *grayptr2 = grayptr + gx; for (i = _gray_info.depth; i > 0; i--) { @@ -805,6 +899,7 @@ static void gray_screendump_hook(int fd) grayptr2 += _gray_info.plane_size; } linebuf[x] = idx; +#endif } else { @@ -823,14 +918,17 @@ static void gray_screendump_hook(int fd) shift = 2 * (y & 3); by = y >> 2; lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by); - gy = y - (_gray_info.by << _PBLOCK_EXP); - + if ((unsigned)gy < (unsigned)_gray_info.height) { /* line contains greyscale (and maybe b&w) graphics */ +#ifdef SIMULATOR + (void)mask; +#else + unsigned char *grayptr = _gray_info.plane_data + + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); mask = 1 << (gy & (_PBLOCK-1)); - grayptr = _gray_info.plane_data - + MULU16(_gray_info.width, gy >> _PBLOCK_EXP); +#endif for (x = 0; x < LCD_WIDTH; x++) { @@ -838,8 +936,12 @@ static void gray_screendump_hook(int fd) if ((unsigned)gx < (unsigned)_gray_info.width) { - idx = BMP_FIXEDCOLORS; - grayptr2 = grayptr + gx; +#ifdef SIMULATOR + linebuf[x] = BMP_FIXEDCOLORS + _gray_info.depth + - _gray_info.cur_buffer[MULU16(gx, _gray_info.height) + gy]; +#else + int idx = BMP_FIXEDCOLORS; + unsigned char *grayptr2 = grayptr + gx; for (i = _gray_info.depth; i > 0; i--) { @@ -848,6 +950,7 @@ static void gray_screendump_hook(int fd) grayptr2 += _gray_info.plane_size; } linebuf[x] = idx; +#endif } else { @@ -862,12 +965,11 @@ static void gray_screendump_hook(int fd) for (x = 0; x < LCD_WIDTH; x++) linebuf[x] = (*lcdptr++ >> shift) & 3; } -#endif +#endif /* LCD_DEPTH */ _gray_rb->write(fd, linebuf, BMP_LINESIZE); } } #endif /* HAVE_LCD_BITMAP */ -#endif /* !SIMULATOR */ diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c index 4222d80dc1..5d73f09e26 100644 --- a/apps/plugins/lib/gray_draw.c +++ b/apps/plugins/lib/gray_draw.c @@ -10,10 +10,10 @@ * Greyscale framework * Drawing functions * -* 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 display up to 33 shades of grey +* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. * -* Copyright (C) 2004-2005 Jens Arnold +* Copyright (C) 2004-2006 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. @@ -23,10 +23,9 @@ * ****************************************************************************/ -#ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#ifdef HAVE_LCD_BITMAP #include "gray.h" /*** low-level drawing functions ***/ @@ -587,6 +586,26 @@ void gray_putsxy(int x, int y, const unsigned char *str) /*** Unbuffered drawing functions ***/ +#ifdef SIMULATOR + +/* Clear the greyscale display (sets all pixels to white) */ +void gray_ub_clear_display(void) +{ + _gray_rb->memset(_gray_info.cur_buffer, _gray_info.depth, + MULU16(_gray_info.width, _gray_info.height)); + gray_update(); +} + +/* 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) +{ + gray_gray_bitmap_part(src, src_x, src_y, stride, x, y, width, height); + gray_update_rect(x, y, width, height); +} + +#else /* !SIMULATOR */ + /* Clear the greyscale display (sets all pixels to white) */ void gray_ub_clear_display(void) { @@ -1005,6 +1024,8 @@ void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, while (dst < dst_end); } +#endif /* !SIMULATOR */ + /* Draw a full greyscale bitmap, canonical format */ void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width, int height) @@ -1014,5 +1035,4 @@ void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width, #endif /* HAVE_LCD_BITMAP */ -#endif /* !SIMULATOR */ diff --git a/apps/plugins/lib/gray_parm.c b/apps/plugins/lib/gray_parm.c index 77156852c5..c6305421c1 100644 --- a/apps/plugins/lib/gray_parm.c +++ b/apps/plugins/lib/gray_parm.c @@ -10,10 +10,10 @@ * Greyscale framework * Parameter handling * -* 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 display up to 33 shades of grey +* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. * -* Copyright (C) 2004-2005 Jens Arnold +* Copyright (C) 2004-2006 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. @@ -23,10 +23,9 @@ * ****************************************************************************/ -#ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#ifdef HAVE_LCD_BITMAP #include "gray.h" /* Set position of the top left corner of the greyscale overlay @@ -37,7 +36,14 @@ void gray_set_position(int x, int by) _gray_info.by = by; if (_gray_info.flags & _GRAY_RUNNING) + { +#ifdef SIMULATOR + gray_deferred_lcd_update(); + gray_update(); +#else _gray_info.flags |= _GRAY_DEFERRED_UPDATE; +#endif + } } /* Set the draw mode for subsequent drawing operations */ @@ -103,5 +109,3 @@ int gray_getstringsize(const unsigned char *str, int *w, int *h) } #endif /* HAVE_LCD_BITMAP */ -#endif /* !SIMULATOR */ - diff --git a/apps/plugins/lib/gray_scroll.c b/apps/plugins/lib/gray_scroll.c index 89ca2f37c3..bb6e0ea5bd 100644 --- a/apps/plugins/lib/gray_scroll.c +++ b/apps/plugins/lib/gray_scroll.c @@ -10,10 +10,10 @@ * Greyscale framework * Scrolling routines * -* 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 display up to 33 shades of grey +* on low-depth bitmap LCDs (Archos b&w, Iriver 4-grey) within plugins. * -* Copyright (C) 2004-2005 Jens Arnold +* Copyright (C) 2004-2006 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. @@ -23,10 +23,9 @@ * ****************************************************************************/ -#ifndef SIMULATOR /* not for simulator by now */ #include "plugin.h" -#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ +#ifdef HAVE_LCD_BITMAP #include "gray.h" /*** Scrolling ***/ @@ -117,6 +116,38 @@ void gray_scroll_down(int count) /*** Unbuffered scrolling functions ***/ +#ifdef SIMULATOR + +/* Scroll left */ +void gray_ub_scroll_left(int count) +{ + gray_scroll_left(count); + gray_update(); +} + +/* Scroll right */ +void gray_ub_scroll_right(int count) +{ + gray_scroll_right(count); + gray_update(); +} + +/* Scroll up */ +void gray_ub_scroll_up(int count) +{ + gray_scroll_up(count); + gray_update(); +} + +/* Scroll down */ +void gray_ub_scroll_down(int count) +{ + gray_scroll_down(count); + gray_update(); +} + +#else /* !SIMULATOR */ + /* Scroll left */ void gray_ub_scroll_left(int count) { @@ -545,7 +576,7 @@ void gray_ub_scroll_down(int count) #endif } } +#endif /* !SIMULATOR */ #endif /* HAVE_LCD_BITMAP */ -#endif /* !SIMULATOR */ diff --git a/apps/plugins/mandelbrot.c b/apps/plugins/mandelbrot.c index 2020d4dc2f..d4e399c057 100644 --- a/apps/plugins/mandelbrot.c +++ b/apps/plugins/mandelbrot.c @@ -20,7 +20,7 @@ ****************************************************************************/ #include "plugin.h" -#if defined(HAVE_LCD_BITMAP) && ((LCD_DEPTH >= 8) || !defined(SIMULATOR)) +#ifdef HAVE_LCD_BITMAP #include "gray.h" #include "xlcd.h" diff --git a/apps/plugins/plasma.c b/apps/plugins/plasma.c index ca589d77b6..934def4434 100644 --- a/apps/plugins/plasma.c +++ b/apps/plugins/plasma.c @@ -24,7 +24,7 @@ #include "plugin.h" -#if defined(HAVE_LCD_BITMAP) && (defined(HAVE_LCD_COLOR) || !defined(SIMULATOR)) +#ifdef HAVE_LCD_BITMAP #ifndef HAVE_LCD_COLOR #include "gray.h" @@ -336,4 +336,4 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) return ret; } -#endif // HAVE_LCD_BITMAP && (HAVE_LCD_COLOR || !SIMULATOR) +#endif /* HAVE_LCD_BITMAP */ diff --git a/uisimulator/sdl/lcd-bitmap.c b/uisimulator/sdl/lcd-bitmap.c index 2fd7576ecc..788a5f662d 100644 --- a/uisimulator/sdl/lcd-bitmap.c +++ b/uisimulator/sdl/lcd-bitmap.c @@ -22,6 +22,7 @@ #include "lcd-sdl.h" SDL_Surface* lcd_surface; +int lcd_backlight_val; #if LCD_DEPTH <= 8 SDL_Color lcd_color_zero = {UI_LCD_BGCOLOR, 0}; @@ -29,22 +30,27 @@ SDL_Color lcd_backlight_color_zero = {UI_LCD_BGCOLORLIGHT, 0}; SDL_Color lcd_color_max = {0, 0, 0, 0}; #endif -static inline Uint32 get_lcd_pixel(int x, int y) +#if LCD_DEPTH < 8 +int lcd_ex_shades = 0; +unsigned long (*lcd_ex_getpixel)(int, int) = NULL; +#endif + +static unsigned long get_lcd_pixel(int x, int y) { #if LCD_DEPTH == 1 - return ((lcd_framebuffer[y/8][x] >> (y & 7)) & 1); + return ((lcd_framebuffer[y/8][x] >> (y & 7)) & 1); #elif LCD_DEPTH == 2 #if LCD_PIXELFORMAT == HORIZONTAL_PACKING - return ((lcd_framebuffer[y][x/4] >> (2 * (x & 3))) & 3); + return ((lcd_framebuffer[y][x/4] >> (2 * (x & 3))) & 3); #else - return ((lcd_framebuffer[y/4][x] >> (2 * (y & 3))) & 3); + return ((lcd_framebuffer[y/4][x] >> (2 * (y & 3))) & 3); #endif #elif LCD_DEPTH == 16 #if LCD_PIXELFORMAT == RGB565SWAPPED - unsigned bits = lcd_framebuffer[y][x]; - return (bits >> 8) | (bits << 8); + unsigned bits = lcd_framebuffer[y][x]; + return (bits >> 8) | (bits << 8); #else - return lcd_framebuffer[y][x]; + return lcd_framebuffer[y][x]; #endif #endif } @@ -57,22 +63,41 @@ void lcd_update(void) void lcd_update_rect(int x_start, int y_start, int width, int height) { - sdl_update_rect(lcd_surface, x_start, y_start, width, height, LCD_WIDTH, LCD_HEIGHT, - background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0, - get_lcd_pixel); + sdl_update_rect(lcd_surface, x_start, y_start, width, height, LCD_WIDTH, + LCD_HEIGHT, get_lcd_pixel); + sdl_gui_update(lcd_surface, x_start, y_start, width, height, LCD_WIDTH, + LCD_HEIGHT, background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0); } #ifdef CONFIG_BACKLIGHT void sim_backlight(int value) { + lcd_backlight_val = value; + #if LCD_DEPTH <= 8 if (value > 0) { - sdl_set_gradient(lcd_surface, &lcd_backlight_color_zero, &lcd_color_max, (1<<LCD_DEPTH)); + sdl_set_gradient(lcd_surface, &lcd_backlight_color_zero, + &lcd_color_max, 0, (1<<LCD_DEPTH)); } else { - sdl_set_gradient(lcd_surface, &lcd_color_zero, &lcd_color_max, (1<<LCD_DEPTH)); + sdl_set_gradient(lcd_surface, &lcd_color_zero, &lcd_color_max, + 0, (1<<LCD_DEPTH)); } - - lcd_update(); +#if LCD_DEPTH < 8 + if (lcd_ex_shades) { + if (value > 0) { + sdl_set_gradient(lcd_surface, &lcd_color_max, + &lcd_backlight_color_zero, (1<<LCD_DEPTH), + lcd_ex_shades); + } else { + sdl_set_gradient(lcd_surface, &lcd_color_max, &lcd_color_zero, + (1<<LCD_DEPTH), lcd_ex_shades); + } + } +#endif + + sdl_gui_update(lcd_surface, 0, 0, LCD_WIDTH, LCD_HEIGHT, LCD_WIDTH, + LCD_HEIGHT, background ? UI_LCD_POSX : 0, background? UI_LCD_POSY : 0); + #else DEBUGF("backlight: %s\n", (value > 0) ? "on" : "off"); #endif @@ -91,7 +116,41 @@ void sim_lcd_init(void) #endif #if LCD_DEPTH <= 8 - sdl_set_gradient(lcd_surface, &lcd_color_zero, &lcd_color_max, (1<<LCD_DEPTH)); + sdl_set_gradient(lcd_surface, &lcd_backlight_color_zero, &lcd_color_max, + 0, (1<<LCD_DEPTH)); +#endif +} + +#if LCD_DEPTH < 8 +void sim_lcd_ex_init(int shades, unsigned long (*getpixel)(int, int)) +{ + lcd_ex_shades = shades; + lcd_ex_getpixel = getpixel; + if (shades) { +#ifdef CONFIG_BACKLIGHT + if (lcd_backlight_val > 0) { + sdl_set_gradient(lcd_surface, &lcd_color_max, + &lcd_backlight_color_zero, (1<<LCD_DEPTH), + shades); + } + else #endif + { + sdl_set_gradient(lcd_surface, &lcd_color_max, &lcd_color_zero, + (1<<LCD_DEPTH), shades); + } + } } +void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height) +{ + if (lcd_ex_getpixel) { + sdl_update_rect(lcd_surface, x_start, y_start, width, height, + LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel); + sdl_gui_update(lcd_surface, x_start, y_start, width, height, LCD_WIDTH, + LCD_HEIGHT, background ? UI_LCD_POSX : 0, + background? UI_LCD_POSY : 0); + } +} +#endif + diff --git a/uisimulator/sdl/lcd-bitmap.h b/uisimulator/sdl/lcd-bitmap.h index 514c4d3ffb..31403385b9 100644 --- a/uisimulator/sdl/lcd-bitmap.h +++ b/uisimulator/sdl/lcd-bitmap.h @@ -24,6 +24,10 @@ #include "SDL.h" void sim_lcd_init(void); +#if LCD_DEPTH < 8 +void sim_lcd_ex_init(int shades, unsigned long (*getpixel)(int, int)); +void sim_lcd_ex_update_rect(int x, int y, int width, int height); +#endif #endif // #ifndef __LCDBITMAP_H__ diff --git a/uisimulator/sdl/lcd-charcell.c b/uisimulator/sdl/lcd-charcell.c index 2ef86d0baf..89c46f7738 100644 --- a/uisimulator/sdl/lcd-charcell.c +++ b/uisimulator/sdl/lcd-charcell.c @@ -109,9 +109,11 @@ void drawrectangles(int color, struct rectangle *points, int count) void sim_backlight(int value) { if (value > 0) { - sdl_set_gradient(lcd_surface, &lcd_backlight_color_zero, &lcd_color_max, (1<<LCD_DEPTH)); + sdl_set_gradient(lcd_surface, &lcd_backlight_color_zero, &lcd_color_max, + 0, (1<<LCD_DEPTH)); } else { - sdl_set_gradient(lcd_surface, &lcd_color_zero, &lcd_color_max, (1<<LCD_DEPTH)); + sdl_set_gradient(lcd_surface, &lcd_color_zero, &lcd_color_max, + 0, (1<<LCD_DEPTH)); } lcd_update(); @@ -124,6 +126,7 @@ void sim_lcd_init(void) lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, LCD_WIDTH * display_zoom, LCD_HEIGHT * display_zoom, 8, 0, 0, 0, 0); - sdl_set_gradient(lcd_surface, &lcd_color_zero, &lcd_color_max, (1<<LCD_DEPTH)); + sdl_set_gradient(lcd_surface, &lcd_backlight_color_zero, &lcd_color_max, + 0, (1<<LCD_DEPTH)); } diff --git a/uisimulator/sdl/lcd-remote.c b/uisimulator/sdl/lcd-remote.c index 64b641ad6d..f1d04b33f8 100644 --- a/uisimulator/sdl/lcd-remote.c +++ b/uisimulator/sdl/lcd-remote.c @@ -41,19 +41,26 @@ void lcd_remote_update (void) void lcd_remote_update_rect(int x_start, int y_start, int width, int height) { sdl_update_rect(remote_surface, x_start, y_start, width, height, + LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, get_lcd_remote_pixel); + sdl_gui_update(remote_surface, x_start, y_start, width, height, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, background ? UI_REMOTE_POSX : 0, - (background ? UI_REMOTE_POSY : LCD_HEIGHT), get_lcd_remote_pixel); + background ? UI_REMOTE_POSY : LCD_HEIGHT); } void sim_remote_backlight(int value) { if (value > 0) { - sdl_set_gradient(remote_surface, &remote_backlight_color_zero, &remote_color_max, (1<<LCD_REMOTE_DEPTH)); + sdl_set_gradient(remote_surface, &remote_backlight_color_zero, + &remote_color_max, 0, (1<<LCD_REMOTE_DEPTH)); } else { - sdl_set_gradient(remote_surface, &remote_color_zero, &remote_color_max, (1<<LCD_REMOTE_DEPTH)); + sdl_set_gradient(remote_surface, &remote_color_zero, &remote_color_max, + 0, (1<<LCD_REMOTE_DEPTH)); } - lcd_remote_update(); + sdl_gui_update(remote_surface, 0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, + LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, + background ? UI_REMOTE_POSX : 0, + background? UI_REMOTE_POSY : LCD_HEIGHT); } /* initialise simulator lcd remote driver */ @@ -63,7 +70,7 @@ void sim_lcd_remote_init(void) LCD_REMOTE_WIDTH * display_zoom, LCD_REMOTE_HEIGHT * display_zoom, 8, 0, 0, 0, 0); - sdl_set_gradient(remote_surface, &remote_color_zero, &remote_color_max, - (1<<LCD_REMOTE_DEPTH)); + sdl_set_gradient(remote_surface, &remote_backlight_color_zero, + &remote_color_max, 0, (1<<LCD_REMOTE_DEPTH)); } diff --git a/uisimulator/sdl/lcd-sdl.c b/uisimulator/sdl/lcd-sdl.c index 3327dd8350..be10b468cb 100644 --- a/uisimulator/sdl/lcd-sdl.c +++ b/uisimulator/sdl/lcd-sdl.c @@ -23,8 +23,8 @@ int display_zoom = 1; void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width, - int height, int max_x, int max_y, int ui_x, int ui_y, - Uint32 (*getpixel)(int, int)) + int height, int max_x, int max_y, + unsigned long (*getpixel)(int, int)) { int x, y; int xmax, ymax; @@ -49,25 +49,39 @@ void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width, for (y = y_start; y < ymax; y++) { dest.y = y * display_zoom; - SDL_FillRect(surface, &dest, getpixel(x, y)); + SDL_FillRect(surface, &dest, (Uint32)getpixel(x, y)); } } SDL_UnlockSurface(surface); +} + +void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width, + int height, int max_x, int max_y, int ui_x, int ui_y) +{ + int xmax, ymax; + + ymax = y_start + height; + xmax = x_start + width; + + if(xmax > max_x) + xmax = max_x; + if(ymax >= max_y) + ymax = max_y; + + SDL_Rect src = {x_start * display_zoom, y_start * display_zoom, + xmax * display_zoom, ymax * display_zoom}; + SDL_Rect dest= {(ui_x + x_start) * display_zoom, (ui_y + y_start) * display_zoom, + xmax * display_zoom, ymax * display_zoom}; - SDL_Rect src = {x_start * display_zoom, y_start * display_zoom, xmax * display_zoom, ymax * display_zoom}; - dest.x = (ui_x + x_start) * display_zoom; - dest.y = (ui_y + y_start) * display_zoom;; - dest.w = xmax * display_zoom; - dest.h = ymax * display_zoom; - SDL_BlitSurface(surface, &src, gui_surface, &dest); SDL_UpdateRect(gui_surface, dest.x, dest.y, dest.w, dest.h); SDL_Flip(gui_surface); } /* set a range of bitmap indices to a gradient from startcolour to endcolour */ -void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, int steps) +void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, + int first, int steps) { int i; SDL_Color palette[steps]; @@ -78,6 +92,6 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, in palette[i].b = start->b + (end->b - start->b) * i / (steps - 1); } - SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, 0, steps); + SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, first, steps); } diff --git a/uisimulator/sdl/lcd-sdl.h b/uisimulator/sdl/lcd-sdl.h index d371639a64..10c2ea74b5 100644 --- a/uisimulator/sdl/lcd-sdl.h +++ b/uisimulator/sdl/lcd-sdl.h @@ -27,11 +27,14 @@ extern int display_zoom; void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width, - int height, int max_x, int max_y, int ui_x, int ui_y, - Uint32 (*getpixel)(int, int)); + int height, int max_x, int max_y, + unsigned long (*getpixel)(int, int)); + +void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width, + int height, int max_x, int max_y, int ui_x, int ui_y); void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end, - int steps); + int first, int steps); #endif // #ifndef __LCDSDL_H__ |