summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-02-26 13:37:42 +0000
committerJens Arnold <amiconn@rockbox.org>2006-02-26 13:37:42 +0000
commit6a972e02497d3015236189f72931c3d59fa51755 (patch)
tree0c0185dd66b47d7d1ee2d91e4a3ffb6dbabcc7d1
parent14fe89aa8d2ef05595bdba0e0b78f021f3e8d087 (diff)
downloadrockbox-6a972e02497d3015236189f72931c3d59fa51755.tar.gz
rockbox-6a972e02497d3015236189f72931c3d59fa51755.zip
Finally - grayscale library support for the simulators. Currently SDL only, win32 and x11 won't link anymore due to missing simulator functions.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8845 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugin.c6
-rw-r--r--apps/plugin.h6
-rw-r--r--apps/plugins/brickmania.c1
-rw-r--r--apps/plugins/cube.c2
-rw-r--r--apps/plugins/fire.c2
-rw-r--r--apps/plugins/grayscale.c2
-rw-r--r--apps/plugins/jpeg.c4
-rw-r--r--apps/plugins/lib/SOURCES3
-rw-r--r--apps/plugins/lib/gray.h18
-rw-r--r--apps/plugins/lib/gray_core.c206
-rw-r--r--apps/plugins/lib/gray_draw.c32
-rw-r--r--apps/plugins/lib/gray_parm.c18
-rw-r--r--apps/plugins/lib/gray_scroll.c43
-rw-r--r--apps/plugins/mandelbrot.c2
-rw-r--r--apps/plugins/plasma.c4
-rw-r--r--uisimulator/sdl/lcd-bitmap.c89
-rw-r--r--uisimulator/sdl/lcd-bitmap.h4
-rw-r--r--uisimulator/sdl/lcd-charcell.c9
-rw-r--r--uisimulator/sdl/lcd-remote.c19
-rw-r--r--uisimulator/sdl/lcd-sdl.c36
-rw-r--r--uisimulator/sdl/lcd-sdl.h9
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__