Colour targets: Adapted mandelbrot plugin. The plugin library now contains scrolling routines for >= 8 bpp displays.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8578 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1a03c37947
commit
e49cade42d
3 changed files with 245 additions and 38 deletions
|
@ -105,5 +105,119 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
|
|||
}
|
||||
}
|
||||
|
||||
#if LCD_DEPTH >= 8
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void xlcd_scroll_left(int count)
|
||||
{
|
||||
fb_data *data, *data_end;
|
||||
int length, oldmode;
|
||||
|
||||
if ((unsigned)count >= LCD_WIDTH)
|
||||
return;
|
||||
|
||||
data = local_rb->lcd_framebuffer;
|
||||
data_end = data + LCD_WIDTH*LCD_HEIGHT;
|
||||
length = LCD_WIDTH - count;
|
||||
|
||||
do
|
||||
{
|
||||
my_memmove(data, data + count, length * sizeof(fb_data));
|
||||
data += LCD_WIDTH;
|
||||
}
|
||||
while (data < data_end);
|
||||
|
||||
oldmode = local_rb->lcd_get_drawmode();
|
||||
local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||
local_rb->lcd_fillrect(length, 0, count, LCD_HEIGHT);
|
||||
local_rb->lcd_set_drawmode(oldmode);
|
||||
}
|
||||
|
||||
void xlcd_scroll_right(int count)
|
||||
{
|
||||
fb_data *data, *data_end;
|
||||
int length, oldmode;
|
||||
|
||||
if ((unsigned)count >= LCD_WIDTH)
|
||||
return;
|
||||
|
||||
data = local_rb->lcd_framebuffer;
|
||||
data_end = data + LCD_WIDTH*LCD_HEIGHT;
|
||||
length = LCD_WIDTH - count;
|
||||
|
||||
do
|
||||
{
|
||||
my_memmove(data + count, data, length * sizeof(fb_data));
|
||||
data += LCD_WIDTH;
|
||||
}
|
||||
while (data < data_end);
|
||||
|
||||
oldmode = local_rb->lcd_get_drawmode();
|
||||
local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||
local_rb->lcd_fillrect(0, 0, count, LCD_HEIGHT);
|
||||
local_rb->lcd_set_drawmode(oldmode);
|
||||
}
|
||||
|
||||
void xlcd_scroll_up(int count)
|
||||
{
|
||||
long length, oldmode;
|
||||
|
||||
if ((unsigned)count >= LCD_HEIGHT)
|
||||
return;
|
||||
|
||||
length = LCD_HEIGHT - count;
|
||||
|
||||
my_memmove(local_rb->lcd_framebuffer,
|
||||
local_rb->lcd_framebuffer + count * LCD_WIDTH,
|
||||
length * LCD_WIDTH * sizeof(fb_data));
|
||||
|
||||
oldmode = local_rb->lcd_get_drawmode();
|
||||
local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||
local_rb->lcd_fillrect(0, length, LCD_WIDTH, count);
|
||||
local_rb->lcd_set_drawmode(oldmode);
|
||||
}
|
||||
|
||||
void xlcd_scroll_down(int count)
|
||||
{
|
||||
long length, oldmode;
|
||||
|
||||
if ((unsigned)count >= LCD_HEIGHT)
|
||||
return;
|
||||
|
||||
length = LCD_HEIGHT - count;
|
||||
|
||||
my_memmove(local_rb->lcd_framebuffer + count * LCD_WIDTH,
|
||||
local_rb->lcd_framebuffer,
|
||||
length * LCD_WIDTH * sizeof(fb_data));
|
||||
|
||||
oldmode = local_rb->lcd_get_drawmode();
|
||||
local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||
local_rb->lcd_fillrect(0, 0, LCD_WIDTH, count);
|
||||
local_rb->lcd_set_drawmode(oldmode);
|
||||
}
|
||||
|
||||
#endif /* LCD_DEPTH >= 8 */
|
||||
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
|
||||
|
|
|
@ -29,6 +29,11 @@
|
|||
void xlcd_init(struct plugin_api* newrb);
|
||||
void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
|
||||
void xlcd_scroll_left(int count);
|
||||
void xlcd_scroll_right(int count);
|
||||
void xlcd_scroll_up(int count);
|
||||
void xlcd_scroll_down(int count);
|
||||
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
#endif /* __XLCD_H__ */
|
||||
|
||||
|
|
|
@ -18,17 +18,21 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef SIMULATOR
|
||||
#include "plugin.h"
|
||||
|
||||
#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4)
|
||||
#if defined(HAVE_LCD_BITMAP) && ((LCD_DEPTH >= 8) || !defined(SIMULATOR))
|
||||
#include "gray.h"
|
||||
#include "xlcd.h"
|
||||
|
||||
PLUGIN_HEADER
|
||||
|
||||
/* variable button definitions */
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
#define MANDELBROT_QUIT BUTTON_OFF
|
||||
#define MANDELBROT_UP BUTTON_UP
|
||||
#define MANDELBROT_DOWN BUTTON_DOWN
|
||||
#define MANDELBROT_LEFT BUTTON_LEFT
|
||||
#define MANDELBROT_RIGHT BUTTON_RIGHT
|
||||
#define MANDELBROT_ZOOM_IN BUTTON_PLAY
|
||||
#define MANDELBROT_ZOOM_OUT BUTTON_ON
|
||||
#define MANDELBROT_MAXITER_INC BUTTON_F2
|
||||
|
@ -37,6 +41,10 @@ PLUGIN_HEADER
|
|||
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
#define MANDELBROT_QUIT BUTTON_OFF
|
||||
#define MANDELBROT_UP BUTTON_UP
|
||||
#define MANDELBROT_DOWN BUTTON_DOWN
|
||||
#define MANDELBROT_LEFT BUTTON_LEFT
|
||||
#define MANDELBROT_RIGHT BUTTON_RIGHT
|
||||
#define MANDELBROT_ZOOM_IN_PRE BUTTON_MENU
|
||||
#define MANDELBROT_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
|
||||
#define MANDELBROT_ZOOM_IN2 (BUTTON_MENU | BUTTON_UP)
|
||||
|
@ -45,17 +53,57 @@ PLUGIN_HEADER
|
|||
#define MANDELBROT_MAXITER_DEC (BUTTON_MENU | BUTTON_LEFT)
|
||||
#define MANDELBROT_RESET (BUTTON_MENU | BUTTON_OFF)
|
||||
|
||||
#elif CONFIG_KEYPAD == IRIVER_H100_PAD
|
||||
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
||||
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
||||
#define MANDELBROT_QUIT BUTTON_OFF
|
||||
#define MANDELBROT_UP BUTTON_UP
|
||||
#define MANDELBROT_DOWN BUTTON_DOWN
|
||||
#define MANDELBROT_LEFT BUTTON_LEFT
|
||||
#define MANDELBROT_RIGHT BUTTON_RIGHT
|
||||
#define MANDELBROT_ZOOM_IN BUTTON_SELECT
|
||||
#define MANDELBROT_ZOOM_OUT BUTTON_MODE
|
||||
#define MANDELBROT_MAXITER_INC (BUTTON_ON | BUTTON_RIGHT)
|
||||
#define MANDELBROT_MAXITER_DEC (BUTTON_ON | BUTTON_LEFT)
|
||||
#define MANDELBROT_RESET BUTTON_REC
|
||||
|
||||
#elif CONFIG_KEYPAD == IPOD_4G_PAD
|
||||
#define MANDELBROT_QUIT (BUTTON_SELECT | BUTTON_MENU)
|
||||
#define MANDELBROT_UP BUTTON_MENU
|
||||
#define MANDELBROT_DOWN BUTTON_PLAY
|
||||
#define MANDELBROT_LEFT BUTTON_LEFT
|
||||
#define MANDELBROT_RIGHT BUTTON_RIGHT
|
||||
#define MANDELBROT_ZOOM_IN BUTTON_SCROLL_FWD
|
||||
#define MANDELBROT_ZOOM_OUT BUTTON_SCROLL_BACK
|
||||
#define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define MANDELBROT_RESET (BUTTON_SELECT | BUTTON_PLAY)
|
||||
|
||||
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
|
||||
#define MANDELBROT_QUIT BUTTON_POWER
|
||||
#define MANDELBROT_UP BUTTON_UP
|
||||
#define MANDELBROT_DOWN BUTTON_DOWN
|
||||
#define MANDELBROT_LEFT BUTTON_LEFT
|
||||
#define MANDELBROT_RIGHT BUTTON_RIGHT
|
||||
#define MANDELBROT_ZOOM_IN_PRE BUTTON_MENU
|
||||
#define MANDELBROT_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
|
||||
#define MANDELBROT_ZOOM_OUT (BUTTON_MENU | BUTTON_REPEAT)
|
||||
#define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_RIGHT)
|
||||
#define MANDELBROT_MAXITER_DEC (BUTTON_PLAY | BUTTON_LEFT)
|
||||
#define MANDELBROT_RESET BUTTON_REC
|
||||
#endif
|
||||
|
||||
#if LCD_DEPTH < 8
|
||||
#define USEGSLIB
|
||||
#define MYLCD(fn) gray_ub_ ## fn
|
||||
#define MYLCD_UPDATE()
|
||||
#define MYXLCD(fn) gray_ub_ ## fn
|
||||
#else
|
||||
#define MYLCD(fn) rb->lcd_ ## fn
|
||||
#define MYLCD_UPDATE() rb->lcd_update();
|
||||
#define MYXLCD(fn) xlcd_ ## fn
|
||||
#endif
|
||||
|
||||
static struct plugin_api* rb;
|
||||
static char buff[32];
|
||||
|
||||
/* Fixed point format: 6 bits integer part incl. sign, 26 bits fractional part */
|
||||
static long x_min;
|
||||
|
@ -75,9 +123,26 @@ static int py_max = LCD_HEIGHT;
|
|||
static int step_log2;
|
||||
static unsigned max_iter;
|
||||
|
||||
#ifdef USEGSLIB
|
||||
static unsigned char *gbuf;
|
||||
static unsigned int gbuf_size = 0;
|
||||
static unsigned char graybuffer[LCD_HEIGHT];
|
||||
static unsigned char imgbuffer[LCD_HEIGHT];
|
||||
#else
|
||||
static fb_data imgbuffer[LCD_HEIGHT];
|
||||
#endif
|
||||
|
||||
/* 8 entries cyclical, last entry is black (convergence) */
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
static const fb_data color[9] = {
|
||||
LCD_RGBPACK(255, 0, 159), LCD_RGBPACK(159, 0, 255), LCD_RGBPACK(0, 0, 255),
|
||||
LCD_RGBPACK(0, 159, 255), LCD_RGBPACK(0, 255, 128), LCD_RGBPACK(128, 255, 0),
|
||||
LCD_RGBPACK(255, 191, 0), LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(0, 0, 0)
|
||||
};
|
||||
#else /* greyscale */
|
||||
static const fb_data color[9] = {
|
||||
255, 223, 191, 159, 128, 96, 64, 32, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_CPU == SH7034
|
||||
|
||||
|
@ -244,7 +309,7 @@ void init_mandelbrot_set(void)
|
|||
#if CONFIG_LCD == LCD_SSD1815 /* Recorder, Ondio. */
|
||||
x_min = -38L<<22; // -2.375<<26
|
||||
x_max = 15L<<22; // 0.9375<<26
|
||||
#else /* Iriver H1x0 */
|
||||
#else /* all others (square pixels) */
|
||||
x_min = -36L<<22; // -2.25<<26
|
||||
x_max = 12L<<22; // 0.75<<26
|
||||
#endif
|
||||
|
@ -260,7 +325,6 @@ void calc_mandelbrot_low_prec(void)
|
|||
long a32, b32;
|
||||
short x, x2, y, y2, a, b;
|
||||
int p_x, p_y;
|
||||
int brightness;
|
||||
|
||||
start_tick = last_yield = *rb->current_tick;
|
||||
|
||||
|
@ -286,13 +350,11 @@ void calc_mandelbrot_low_prec(void)
|
|||
x = x2 - y2 + a;
|
||||
}
|
||||
|
||||
// "coloring"
|
||||
if (n_iter > max_iter){
|
||||
brightness = 0; // black
|
||||
} else {
|
||||
brightness = 255 - (32 * (n_iter & 7));
|
||||
}
|
||||
graybuffer[p_y] = brightness;
|
||||
if (n_iter > max_iter)
|
||||
imgbuffer[p_y] = color[8];
|
||||
else
|
||||
imgbuffer[p_y] = color[n_iter & 7];
|
||||
|
||||
/* be nice to other threads:
|
||||
* if at least one tick has passed, yield */
|
||||
if (*rb->current_tick > last_yield) {
|
||||
|
@ -300,8 +362,14 @@ void calc_mandelbrot_low_prec(void)
|
|||
last_yield = *rb->current_tick;
|
||||
}
|
||||
}
|
||||
gray_ub_gray_bitmap_part(graybuffer, 0, py_min, 1,
|
||||
#ifdef USEGSLIB
|
||||
gray_ub_gray_bitmap_part(imgbuffer, 0, py_min, 1,
|
||||
p_x, py_min, 1, py_max-py_min);
|
||||
#else
|
||||
rb->lcd_bitmap_part(imgbuffer, 0, py_min, 1,
|
||||
p_x, py_min, 1, py_max-py_min);
|
||||
rb->lcd_update_rect(p_x, py_min, 1, py_max-py_min);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,8 +379,7 @@ void calc_mandelbrot_high_prec(void)
|
|||
unsigned n_iter;
|
||||
long x, x2, y, y2, a, b;
|
||||
int p_x, p_y;
|
||||
int brightness;
|
||||
|
||||
|
||||
MULS32_INIT();
|
||||
start_tick = last_yield = *rb->current_tick;
|
||||
|
||||
|
@ -336,13 +403,11 @@ void calc_mandelbrot_high_prec(void)
|
|||
x = x2 - y2 + a;
|
||||
}
|
||||
|
||||
// "coloring"
|
||||
if (n_iter > max_iter){
|
||||
brightness = 0; // black
|
||||
} else {
|
||||
brightness = 255 - (32 * (n_iter & 7));
|
||||
}
|
||||
graybuffer[p_y] = brightness;
|
||||
if (n_iter > max_iter)
|
||||
imgbuffer[p_y] = color[8];
|
||||
else
|
||||
imgbuffer[p_y] = color[n_iter & 7];
|
||||
|
||||
/* be nice to other threads:
|
||||
* if at least one tick has passed, yield */
|
||||
if (*rb->current_tick > last_yield) {
|
||||
|
@ -350,16 +415,23 @@ void calc_mandelbrot_high_prec(void)
|
|||
last_yield = *rb->current_tick;
|
||||
}
|
||||
}
|
||||
gray_ub_gray_bitmap_part(graybuffer, 0, py_min, 1,
|
||||
#ifdef USEGSLIB
|
||||
gray_ub_gray_bitmap_part(imgbuffer, 0, py_min, 1,
|
||||
p_x, py_min, 1, py_max-py_min);
|
||||
#else
|
||||
rb->lcd_bitmap_part(imgbuffer, 0, py_min, 1,
|
||||
p_x, py_min, 1, py_max-py_min);
|
||||
rb->lcd_update_rect(p_x, py_min, 1, py_max-py_min);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup(void *parameter)
|
||||
{
|
||||
(void)parameter;
|
||||
|
||||
#ifdef USEGSLIB
|
||||
gray_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
#define REDRAW_NONE 0
|
||||
|
@ -370,12 +442,16 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|||
{
|
||||
int button;
|
||||
int lastbutton = BUTTON_NONE;
|
||||
int grayscales;
|
||||
int redraw = REDRAW_FULL;
|
||||
#ifdef USEGSLIB
|
||||
int grayscales;
|
||||
char buff[32];
|
||||
#endif
|
||||
|
||||
rb = api;
|
||||
(void)parameter;
|
||||
|
||||
#ifdef USEGSLIB
|
||||
/* get the remainder of the plugin buffer */
|
||||
gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
|
||||
|
||||
|
@ -392,6 +468,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|||
}
|
||||
|
||||
gray_show(true); /* switch on grayscale overlay */
|
||||
#else
|
||||
xlcd_init(rb);
|
||||
#endif
|
||||
|
||||
init_mandelbrot_set();
|
||||
|
||||
|
@ -401,8 +480,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|||
#if !defined(SIMULATOR) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||
rb->cpu_boost(true);
|
||||
#endif
|
||||
if (redraw == REDRAW_FULL)
|
||||
gray_ub_clear_display();
|
||||
if (redraw == REDRAW_FULL) {
|
||||
MYLCD(clear_display)();
|
||||
MYLCD_UPDATE();
|
||||
}
|
||||
|
||||
if (step_log2 <= -10) /* select precision */
|
||||
calc_mandelbrot_high_prec();
|
||||
|
@ -422,7 +503,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|||
button = rb->button_get(true);
|
||||
switch (button) {
|
||||
case MANDELBROT_QUIT:
|
||||
#ifdef USEGSLIB
|
||||
gray_release();
|
||||
#endif
|
||||
return PLUGIN_OK;
|
||||
|
||||
case MANDELBROT_ZOOM_OUT:
|
||||
|
@ -451,34 +534,38 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|||
redraw = REDRAW_FULL;
|
||||
break;
|
||||
|
||||
case BUTTON_UP:
|
||||
case MANDELBROT_UP:
|
||||
y_min += y_delta;
|
||||
y_max += y_delta;
|
||||
gray_ub_scroll_down(LCD_HEIGHT/8);
|
||||
MYXLCD(scroll_down)(LCD_HEIGHT/8);
|
||||
MYLCD_UPDATE();
|
||||
py_max = (LCD_HEIGHT/8);
|
||||
redraw = REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case BUTTON_DOWN:
|
||||
case MANDELBROT_DOWN:
|
||||
y_min -= y_delta;
|
||||
y_max -= y_delta;
|
||||
gray_ub_scroll_up(LCD_HEIGHT/8);
|
||||
MYXLCD(scroll_up)(LCD_HEIGHT/8);
|
||||
MYLCD_UPDATE();
|
||||
py_min = (LCD_HEIGHT-LCD_HEIGHT/8);
|
||||
redraw = REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case BUTTON_LEFT:
|
||||
case MANDELBROT_LEFT:
|
||||
x_min -= x_delta;
|
||||
x_max -= x_delta;
|
||||
gray_ub_scroll_right(LCD_WIDTH/8);
|
||||
MYXLCD(scroll_right)(LCD_WIDTH/8);
|
||||
MYLCD_UPDATE();
|
||||
px_max = (LCD_WIDTH/8);
|
||||
redraw = REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case BUTTON_RIGHT:
|
||||
case MANDELBROT_RIGHT:
|
||||
x_min += x_delta;
|
||||
x_max += x_delta;
|
||||
gray_ub_scroll_left(LCD_WIDTH/8);
|
||||
MYXLCD(scroll_left)(LCD_WIDTH/8);
|
||||
MYLCD_UPDATE();
|
||||
px_min = (LCD_WIDTH-LCD_WIDTH/8);
|
||||
redraw = REDRAW_PARTIAL;
|
||||
break;
|
||||
|
@ -509,8 +596,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
|||
if (button != BUTTON_NONE)
|
||||
lastbutton = button;
|
||||
}
|
||||
#ifdef USEGSLIB
|
||||
gray_release();
|
||||
#endif
|
||||
return PLUGIN_OK;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue