FS#10911 - Plugins: Fractals (formerly Mandelbrot)
- Rename the mandelbrot plugin to fractals - Update manual accordingly - Separate plugin's functionality into separate files - Lay the ground for having fractals sets other than the Mandelbrot set. For that the following will need to be implemented: - Create a new file for the new fracral set - Provide key mapping to switch between sets git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24230 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
51630cbac1
commit
7719d297f2
20 changed files with 1676 additions and 5 deletions
|
@ -41,7 +41,7 @@ keybox,apps
|
|||
lamp,apps
|
||||
logo,demos
|
||||
lua,viewers
|
||||
mandelbrot,demos
|
||||
fractals,demos
|
||||
matrix,demos
|
||||
maze,games
|
||||
mazezam,games
|
||||
|
|
|
@ -77,7 +77,6 @@ codebuster.c
|
|||
|
||||
/* Plugins needing the grayscale lib on low-depth LCDs */
|
||||
fire.c
|
||||
mandelbrot.c
|
||||
plasma.c
|
||||
|
||||
blackjack.c
|
||||
|
|
|
@ -20,6 +20,7 @@ rockboy
|
|||
pictureflow
|
||||
#endif
|
||||
chessbox
|
||||
fractals
|
||||
jpeg
|
||||
sudoku
|
||||
reversi
|
||||
|
|
10
apps/plugins/fractals/SOURCES
Normal file
10
apps/plugins/fractals/SOURCES
Normal file
|
@ -0,0 +1,10 @@
|
|||
fractal.c
|
||||
fractal_rect.c
|
||||
mandelbrot_set.c
|
||||
#if CONFIG_CPU == SH7034
|
||||
cpu_sh7043.c
|
||||
#elif defined CPU_COLDFIRE
|
||||
cpu_coldfire.c
|
||||
#elif defined CPU_ARM
|
||||
cpu_arm.c
|
||||
#endif
|
40
apps/plugins/fractals/cpu_arm.c
Normal file
40
apps/plugins/fractals/cpu_arm.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "cpu_arm.h"
|
||||
|
||||
inline long muls32_asr26(long a, long b)
|
||||
{
|
||||
long r, t1;
|
||||
asm (
|
||||
"smull %[r], %[t1], %[a], %[b] \n"
|
||||
"mov %[r], %[r], lsr #26 \n"
|
||||
"orr %[r], %[r], %[t1], lsl #6 \n"
|
||||
: /* outputs */
|
||||
[r] "=&r,&r,&r"(r),
|
||||
[t1]"=&r,&r,&r"(t1)
|
||||
: /* inputs */
|
||||
[a] "%r,%r,%r" (a),
|
||||
[b] "r,0,1" (b)
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
27
apps/plugins/fractals/cpu_arm.h
Normal file
27
apps/plugins/fractals/cpu_arm.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CPU_ARM_H
|
||||
#define _CPU_ARM_H
|
||||
|
||||
inline long muls32_asr26(long a, long b);
|
||||
|
||||
#endif
|
58
apps/plugins/fractals/cpu_coldfire.c
Normal file
58
apps/plugins/fractals/cpu_coldfire.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "cpu_coldfire.h"
|
||||
|
||||
inline short muls16_asr10(short a, short b)
|
||||
{
|
||||
asm (
|
||||
"muls.w %[a],%[b] \n"
|
||||
"asr.l #8,%[b] \n"
|
||||
"asr.l #2,%[b] \n"
|
||||
: /* outputs */
|
||||
[b]"+d"(b)
|
||||
: /* inputs */
|
||||
[a]"d" (a)
|
||||
);
|
||||
return b;
|
||||
}
|
||||
|
||||
inline long muls32_asr26(long a, long b)
|
||||
{
|
||||
long r, t1;
|
||||
asm (
|
||||
"mac.l %[a], %[b], %%acc0 \n" /* multiply */
|
||||
"move.l %%accext01, %[t1] \n" /* get low part */
|
||||
"movclr.l %%acc0, %[r] \n" /* get high part */
|
||||
"asl.l #5, %[r] \n" /* hi <<= 5, plus one free */
|
||||
"lsr.l #3, %[t1] \n" /* lo >>= 3 */
|
||||
"and.l #0x1f, %[t1] \n" /* mask out unrelated bits */
|
||||
"or.l %[t1], %[r] \n" /* combine result */
|
||||
: /* outputs */
|
||||
[r] "=d"(r),
|
||||
[t1]"=d"(t1)
|
||||
: /* inputs */
|
||||
[a] "d" (a),
|
||||
[b] "d" (b)
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
29
apps/plugins/fractals/cpu_coldfire.h
Normal file
29
apps/plugins/fractals/cpu_coldfire.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CPU_COLDFIRE_H
|
||||
#define _CPU_COLDFIRE_H
|
||||
|
||||
inline short muls16_asr10(short a, short b);
|
||||
|
||||
inline long muls32_asr26(long a, long b);
|
||||
|
||||
#endif
|
94
apps/plugins/fractals/cpu_sh7043.c
Normal file
94
apps/plugins/fractals/cpu_sh7043.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "cpu_sh7043.h"
|
||||
|
||||
inline short muls16_asr10(short a, short b)
|
||||
{
|
||||
short r;
|
||||
asm (
|
||||
"muls %[a],%[b] \n"
|
||||
"sts macl,%[r] \n"
|
||||
"shlr8 %[r] \n"
|
||||
"shlr2 %[r] \n"
|
||||
: /* outputs */
|
||||
[r]"=r"(r)
|
||||
: /* inputs */
|
||||
[a]"r"(a),
|
||||
[b]"r"(b)
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline long muls32_asr26(long a, long b)
|
||||
{
|
||||
long r, t1, t2, t3;
|
||||
asm (
|
||||
/* Signed 32bit * 32bit -> 64bit multiplication.
|
||||
Notation: xxab * xxcd, where each letter represents 16 bits.
|
||||
xx is the 64 bit sign extension. */
|
||||
"swap.w %[a],%[t1] \n" /* t1 = ba */
|
||||
"mulu %[t1],%[b] \n" /* a * d */
|
||||
"swap.w %[b],%[t3] \n" /* t3 = dc */
|
||||
"sts macl,%[t2] \n" /* t2 = a * d */
|
||||
"mulu %[t1],%[t3] \n" /* a * c */
|
||||
"sts macl,%[r] \n" /* hi = a * c */
|
||||
"mulu %[a],%[t3] \n" /* b * c */
|
||||
"clrt \n"
|
||||
"sts macl,%[t3] \n" /* t3 = b * c */
|
||||
"addc %[t2],%[t3] \n" /* t3 += t2, carry -> t2 */
|
||||
"movt %[t2] \n"
|
||||
"mulu %[a],%[b] \n" /* b * d */
|
||||
"mov %[t3],%[t1] \n" /* t1t3 = t2t3 << 16 */
|
||||
"xtrct %[t2],%[t1] \n"
|
||||
"shll16 %[t3] \n"
|
||||
"sts macl,%[t2] \n" /* lo = b * d */
|
||||
"clrt \n" /* hi.lo += t1t3 */
|
||||
"addc %[t3],%[t2] \n"
|
||||
"addc %[t1],%[r] \n"
|
||||
"cmp/pz %[a] \n" /* ab >= 0 ? */
|
||||
"bt 1f \n"
|
||||
"sub %[b],%[r] \n" /* no: hi -= cd (sign extension of ab is -1) */
|
||||
"1: \n"
|
||||
"cmp/pz %[b] \n" /* cd >= 0 ? */
|
||||
"bt 2f \n"
|
||||
"sub %[a],%[r] \n" /* no: hi -= ab (sign extension of cd is -1) */
|
||||
"2: \n"
|
||||
/* Shift right by 26 and return low 32 bits */
|
||||
"shll2 %[r] \n" /* hi <<= 6 */
|
||||
"shll2 %[r] \n"
|
||||
"shll2 %[r] \n"
|
||||
"shlr16 %[t2] \n" /* (unsigned)lo >>= 26 */
|
||||
"shlr8 %[t2] \n"
|
||||
"shlr2 %[t2] \n"
|
||||
"or %[t2],%[r] \n" /* combine result */
|
||||
: /* outputs */
|
||||
[r] "=&r"(r),
|
||||
[t1]"=&r"(t1),
|
||||
[t2]"=&r"(t2),
|
||||
[t3]"=&r"(t3)
|
||||
: /* inputs */
|
||||
[a] "r" (a),
|
||||
[b] "r" (b)
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
29
apps/plugins/fractals/cpu_sh7043.h
Normal file
29
apps/plugins/fractals/cpu_sh7043.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _CPU_SH7043_H
|
||||
#define _CPU_SH7043_H
|
||||
|
||||
inline short muls16_asr10(short a, short b);
|
||||
|
||||
inline long muls32_asr26(long a, long b);
|
||||
|
||||
#endif
|
260
apps/plugins/fractals/fractal.c
Normal file
260
apps/plugins/fractals/fractal.c
Normal file
|
@ -0,0 +1,260 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 Matthias Wientapper
|
||||
* Heavily extended 2005 Jens Arnold
|
||||
* Extended 2009 Tomer Shalev
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "plugin.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
||||
#include "fractal.h"
|
||||
#include "fractal_rect.h"
|
||||
#include "fractal_sets.h"
|
||||
#include "mandelbrot_set.h"
|
||||
|
||||
#if (LCD_DEPTH < 8)
|
||||
#define USEGSLIB
|
||||
#define MYLCD(fn) grey_ub_ ## fn
|
||||
#define MYLCD_UPDATE()
|
||||
#define MYXLCD(fn) grey_ub_ ## fn
|
||||
#else
|
||||
#define MYLCD(fn) rb->lcd_ ## fn
|
||||
#define MYLCD_UPDATE() rb->lcd_update();
|
||||
#define MYXLCD(fn) xlcd_ ## fn
|
||||
#endif
|
||||
|
||||
#ifdef USEGSLIB
|
||||
GREY_INFO_STRUCT
|
||||
static unsigned char *gbuf;
|
||||
static size_t gbuf_size = 0;
|
||||
unsigned char imgbuffer[LCD_HEIGHT];
|
||||
#else
|
||||
fb_data imgbuffer[LCD_HEIGHT];
|
||||
#endif
|
||||
|
||||
#define REDRAW_NONE 0
|
||||
#define REDRAW_PARTIAL 1
|
||||
#define REDRAW_FULL 2
|
||||
|
||||
PLUGIN_HEADER
|
||||
|
||||
/* returns 1 if a button has been pressed, 0 otherwise */
|
||||
static int button_yield(void *ctx)
|
||||
{
|
||||
long *button = (long *)ctx;
|
||||
|
||||
*button = rb->button_get(false);
|
||||
switch (*button)
|
||||
{
|
||||
case FRACTAL_QUIT:
|
||||
case FRACTAL_UP:
|
||||
case FRACTAL_DOWN:
|
||||
case FRACTAL_LEFT:
|
||||
case FRACTAL_RIGHT:
|
||||
case FRACTAL_ZOOM_IN:
|
||||
case FRACTAL_ZOOM_OUT:
|
||||
case FRACTAL_PRECISION_INC:
|
||||
case FRACTAL_PRECISION_DEC:
|
||||
case FRACTAL_RESET:
|
||||
#ifdef FRACTAL_ZOOM_IN2
|
||||
case FRACTAL_ZOOM_IN2:
|
||||
#endif
|
||||
#ifdef FRACTAL_ZOOM_IN_PRE
|
||||
case FRACTAL_ZOOM_IN_PRE:
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
*button = BUTTON_NONE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanup(void *parameter)
|
||||
{
|
||||
(void)parameter;
|
||||
#ifdef USEGSLIB
|
||||
grey_release();
|
||||
#endif
|
||||
}
|
||||
|
||||
enum plugin_status plugin_start(const void* parameter)
|
||||
{
|
||||
long lastbutton = BUTTON_NONE;
|
||||
int redraw = REDRAW_FULL;
|
||||
struct fractal_ops *ops = &mandelbrot_ops;
|
||||
|
||||
(void)parameter;
|
||||
|
||||
#ifdef USEGSLIB
|
||||
/* get the remainder of the plugin buffer */
|
||||
gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size);
|
||||
|
||||
/* initialize the greyscale buffer.*/
|
||||
if (!grey_init(gbuf, gbuf_size, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
|
||||
{
|
||||
rb->splash(HZ, "Couldn't init greyscale display");
|
||||
return 0;
|
||||
}
|
||||
grey_show(true); /* switch on greyscale overlay */
|
||||
#endif
|
||||
|
||||
#if LCD_DEPTH > 1
|
||||
rb->lcd_set_backdrop(NULL);
|
||||
#endif
|
||||
|
||||
ops->init();
|
||||
|
||||
/* main loop */
|
||||
while (true)
|
||||
{
|
||||
long button = BUTTON_NONE;
|
||||
|
||||
if (redraw != REDRAW_NONE)
|
||||
{
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
rb->cpu_boost(true);
|
||||
#endif
|
||||
if (redraw == REDRAW_FULL)
|
||||
{
|
||||
MYLCD(clear_display)();
|
||||
MYLCD_UPDATE();
|
||||
rects_queue_init();
|
||||
}
|
||||
|
||||
/* paint all rects */
|
||||
rects_calc_all(ops->calc, button_yield, (void *)&button);
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
rb->cpu_boost(false);
|
||||
#endif
|
||||
/* not interrupted by button press - screen is fully drawn */
|
||||
redraw = (button == BUTTON_NONE) ? REDRAW_NONE : REDRAW_PARTIAL;
|
||||
}
|
||||
|
||||
if (button == BUTTON_NONE)
|
||||
button = rb->button_get(true);
|
||||
|
||||
switch (button)
|
||||
{
|
||||
#ifdef FRACTAL_RC_QUIT
|
||||
case FRACTAL_RC_QUIT:
|
||||
#endif
|
||||
case FRACTAL_QUIT:
|
||||
#ifdef USEGSLIB
|
||||
grey_release();
|
||||
#endif
|
||||
return PLUGIN_OK;
|
||||
|
||||
case FRACTAL_ZOOM_OUT:
|
||||
#ifdef FRACTAL_ZOOM_OUT_PRE
|
||||
if (lastbutton != FRACTAL_ZOOM_OUT_PRE)
|
||||
break;
|
||||
#endif
|
||||
ops->zoom(-1);
|
||||
redraw = REDRAW_FULL;
|
||||
break;
|
||||
|
||||
|
||||
case FRACTAL_ZOOM_IN:
|
||||
#ifdef FRACTAL_ZOOM_IN_PRE
|
||||
if (lastbutton != FRACTAL_ZOOM_IN_PRE)
|
||||
break;
|
||||
#endif
|
||||
#ifdef FRACTAL_ZOOM_IN2
|
||||
case FRACTAL_ZOOM_IN2:
|
||||
#endif
|
||||
ops->zoom(1);
|
||||
redraw = REDRAW_FULL;
|
||||
break;
|
||||
|
||||
case FRACTAL_UP:
|
||||
ops->move(0, +1);
|
||||
MYXLCD(scroll_down)(LCD_SHIFT_Y);
|
||||
MYLCD_UPDATE();
|
||||
if (redraw != REDRAW_FULL)
|
||||
redraw = rects_move_down() ? REDRAW_FULL : REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case FRACTAL_DOWN:
|
||||
ops->move(0, -1);
|
||||
MYXLCD(scroll_up)(LCD_SHIFT_Y);
|
||||
MYLCD_UPDATE();
|
||||
if (redraw != REDRAW_FULL)
|
||||
redraw = rects_move_up() ? REDRAW_FULL : REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case FRACTAL_LEFT:
|
||||
ops->move(-1, 0);
|
||||
MYXLCD(scroll_right)(LCD_SHIFT_X);
|
||||
MYLCD_UPDATE();
|
||||
if (redraw != REDRAW_FULL)
|
||||
redraw = rects_move_right() ? REDRAW_FULL : REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case FRACTAL_RIGHT:
|
||||
ops->move(+1, 0);
|
||||
MYXLCD(scroll_left)(LCD_SHIFT_X);
|
||||
MYLCD_UPDATE();
|
||||
if (redraw != REDRAW_FULL)
|
||||
redraw = rects_move_left() ? REDRAW_FULL : REDRAW_PARTIAL;
|
||||
break;
|
||||
|
||||
case FRACTAL_PRECISION_DEC:
|
||||
#ifdef FRACTAL_PRECISION_DEC_PRE
|
||||
if (lastbutton != FRACTAL_PRECISION_DEC_PRE)
|
||||
break;
|
||||
#endif
|
||||
if (ops->precision(-1))
|
||||
redraw = REDRAW_FULL;
|
||||
|
||||
break;
|
||||
|
||||
case FRACTAL_PRECISION_INC:
|
||||
#ifdef FRACTAL_PRECISION_INC_PRE
|
||||
if (lastbutton != FRACTAL_PRECISION_INC_PRE)
|
||||
break;
|
||||
#endif
|
||||
if (ops->precision(+1))
|
||||
redraw = REDRAW_FULL;
|
||||
|
||||
break;
|
||||
|
||||
case FRACTAL_RESET:
|
||||
ops->init();
|
||||
redraw = REDRAW_FULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (rb->default_event_handler_ex(button, cleanup, NULL)
|
||||
== SYS_USB_CONNECTED)
|
||||
return PLUGIN_USB_CONNECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (button != BUTTON_NONE)
|
||||
lastbutton = button;
|
||||
}
|
||||
#ifdef USEGSLIB
|
||||
grey_release();
|
||||
#endif
|
||||
return PLUGIN_OK;
|
||||
}
|
||||
|
||||
#endif
|
352
apps/plugins/fractals/fractal.h
Normal file
352
apps/plugins/fractals/fractal.h
Normal file
|
@ -0,0 +1,352 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _FRACTAL_H
|
||||
#define _FRACTAL_H
|
||||
|
||||
/* variable button definitions */
|
||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||
#define FRACTAL_QUIT BUTTON_OFF
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_PLAY
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_ON
|
||||
#define FRACTAL_PRECISION_INC BUTTON_F2
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_F1
|
||||
#define FRACTAL_RESET BUTTON_F3
|
||||
|
||||
#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
|
||||
#define FRACTAL_QUIT BUTTON_OFF
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_ON
|
||||
#define FRACTAL_PRECISION_INC BUTTON_F2
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_F1
|
||||
#define FRACTAL_RESET BUTTON_F3
|
||||
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
#define FRACTAL_QUIT BUTTON_OFF
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_MENU
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_IN2 (BUTTON_MENU | BUTTON_UP)
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_MENU | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_MENU | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET (BUTTON_MENU | BUTTON_OFF)
|
||||
|
||||
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
||||
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
||||
#define FRACTAL_QUIT BUTTON_OFF
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_MODE
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_ON | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_ON | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET BUTTON_REC
|
||||
|
||||
#define FRACTAL_RC_QUIT BUTTON_RC_STOP
|
||||
|
||||
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
|
||||
(CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
||||
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
|
||||
#define FRACTAL_QUIT (BUTTON_SELECT | BUTTON_MENU)
|
||||
#define FRACTAL_UP BUTTON_MENU
|
||||
#define FRACTAL_DOWN BUTTON_PLAY
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_SCROLL_FWD
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_SCROLL_BACK
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET (BUTTON_SELECT | BUTTON_PLAY)
|
||||
|
||||
#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
|
||||
#define FRACTAL_PRECISION_INC_PRE BUTTON_PLAY
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_PLAY | BUTTON_REL)
|
||||
#define FRACTAL_PRECISION_DEC_PRE BUTTON_PLAY
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_PLAY | BUTTON_REPEAT)
|
||||
#define FRACTAL_RESET BUTTON_REC
|
||||
|
||||
#elif CONFIG_KEYPAD == GIGABEAT_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
|
||||
#define FRACTAL_PRECISION_INC BUTTON_VOL_UP
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_VOL_DOWN
|
||||
#define FRACTAL_RESET BUTTON_A
|
||||
|
||||
#elif CONFIG_KEYPAD == SANSA_E200_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_SCROLL_FWD
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_SCROLL_BACK
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET BUTTON_REC
|
||||
|
||||
#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
|
||||
#define FRACTAL_QUIT (BUTTON_HOME|BUTTON_REPEAT)
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_SCROLL_FWD
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_SCROLL_BACK
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET (BUTTON_SELECT | BUTTON_REPEAT)
|
||||
|
||||
#elif CONFIG_KEYPAD == SANSA_C200_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_VOL_UP
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_VOL_DOWN
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET BUTTON_REC
|
||||
|
||||
#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_VOL_UP
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_VOL_DOWN
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET BUTTON_HOME
|
||||
|
||||
#elif CONFIG_KEYPAD == SANSA_M200_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_VOL_UP
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_VOL_DOWN
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_SELECT | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_SELECT | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET (BUTTON_SELECT | BUTTON_UP)
|
||||
|
||||
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_SCROLL_UP
|
||||
#define FRACTAL_DOWN BUTTON_SCROLL_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_PLAY
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_PLAY
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
|
||||
#define FRACTAL_PRECISION_INC BUTTON_FF
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_REW
|
||||
#define FRACTAL_RESET (BUTTON_PLAY | BUTTON_REW)
|
||||
|
||||
#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
|
||||
#define FRACTAL_QUIT BUTTON_EQ
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_PLAY | BUTTON_RIGHT)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_PLAY | BUTTON_LEFT)
|
||||
#define FRACTAL_RESET BUTTON_MODE
|
||||
|
||||
#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
|
||||
#define FRACTAL_QUIT BUTTON_BACK
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_VOL_UP
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_VOL_DOWN
|
||||
#define FRACTAL_PRECISION_INC BUTTON_PREV
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_NEXT
|
||||
#define FRACTAL_RESET BUTTON_MENU
|
||||
|
||||
#elif CONFIG_KEYPAD == MROBE100_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_SELECT
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
|
||||
#define FRACTAL_PRECISION_INC BUTTON_MENU
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_PLAY
|
||||
#define FRACTAL_RESET BUTTON_DISPLAY
|
||||
|
||||
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
|
||||
#define FRACTAL_QUIT BUTTON_RC_REC
|
||||
#define FRACTAL_UP BUTTON_RC_VOL_UP
|
||||
#define FRACTAL_DOWN BUTTON_RC_VOL_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_RC_REW
|
||||
#define FRACTAL_RIGHT BUTTON_RC_FF
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_RC_PLAY
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_RC_PLAY | BUTTON_REL)
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_RC_PLAY
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_RC_PLAY | BUTTON_REPEAT)
|
||||
#define FRACTAL_PRECISION_INC_PRE BUTTON_RC_MODE
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_RC_MODE|BUTTON_REL)
|
||||
#define FRACTAL_PRECISION_DEC_PRE BUTTON_RC_MODE
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_RC_MODE|BUTTON_REPEAT)
|
||||
#define FRACTAL_RESET BUTTON_RC_MENU
|
||||
|
||||
#elif CONFIG_KEYPAD == COWON_D2_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
|
||||
#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
|
||||
#define FRACTAL_QUIT BUTTON_BACK
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_PLAY
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_MENU
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_UP | BUTTON_CUSTOM)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_DOWN | BUTTON_CUSTOM)
|
||||
#define FRACTAL_RESET BUTTON_SELECT
|
||||
|
||||
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_VIEW
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_PLAYLIST
|
||||
#define FRACTAL_PRECISION_INC BUTTON_VOL_UP
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_VOL_DOWN
|
||||
#define FRACTAL_RESET BUTTON_MENU
|
||||
|
||||
#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_PREV
|
||||
#define FRACTAL_RIGHT BUTTON_NEXT
|
||||
#define FRACTAL_ZOOM_IN BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_OUT BUTTON_LEFT
|
||||
#define FRACTAL_PRECISION_INC BUTTON_VOL_UP
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_VOL_DOWN
|
||||
#define FRACTAL_RESET BUTTON_MENU
|
||||
|
||||
#elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
|
||||
#elif CONFIG_KEYPAD == ONDAVX777_PAD
|
||||
#define FRACTAL_QUIT BUTTON_POWER
|
||||
|
||||
#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
|
||||
#define FRACTAL_QUIT BUTTON_REC
|
||||
#define FRACTAL_UP BUTTON_UP
|
||||
#define FRACTAL_DOWN BUTTON_DOWN
|
||||
#define FRACTAL_LEFT BUTTON_LEFT
|
||||
#define FRACTAL_RIGHT BUTTON_RIGHT
|
||||
#define FRACTAL_ZOOM_IN_PRE (BUTTON_FFWD | BUTTON_UP)
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_REW | BUTTON_UP)
|
||||
#define FRACTAL_ZOOM_OUT_PRE (BUTTON_FFWD | BUTTON_DOWN)
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_REW | BUTTON_DOWN)
|
||||
#define FRACTAL_PRECISION_INC (BUTTON_PLAY | BUTTON_UP)
|
||||
#define FRACTAL_PRECISION_DEC (BUTTON_FFWD | BUTTON_DOWN)
|
||||
#define FRACTAL_RESET (BUTTON_PLAY | BUTTON_RIGHT)
|
||||
|
||||
#else
|
||||
#error No keymap defined!
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TOUCHSCREEN
|
||||
#ifndef FRACTAL_UP
|
||||
#define FRACTAL_UP BUTTON_TOPMIDDLE
|
||||
#endif
|
||||
#ifndef FRACTAL_DOWN
|
||||
#define FRACTAL_DOWN BUTTON_BOTTOMMIDDLE
|
||||
#endif
|
||||
#ifndef FRACTAL_LEFT
|
||||
#define FRACTAL_LEFT BUTTON_MIDLEFT
|
||||
#endif
|
||||
#ifndef FRACTAL_RIGHT
|
||||
#define FRACTAL_RIGHT BUTTON_MIDRIGHT
|
||||
#endif
|
||||
#ifndef FRACTAL_ZOOM_IN_PRE
|
||||
#define FRACTAL_ZOOM_IN_PRE BUTTON_TOPRIGHT
|
||||
#endif
|
||||
#ifndef FRACTAL_ZOOM_IN
|
||||
#define FRACTAL_ZOOM_IN (BUTTON_TOPRIGHT | BUTTON_REL)
|
||||
#endif
|
||||
#ifndef FRACTAL_ZOOM_OUT_PRE
|
||||
#define FRACTAL_ZOOM_OUT_PRE BUTTON_TOPLEFT
|
||||
#endif
|
||||
#ifndef FRACTAL_ZOOM_OUT
|
||||
#define FRACTAL_ZOOM_OUT (BUTTON_TOPLEFT | BUTTON_REL)
|
||||
#endif
|
||||
#ifndef FRACTAL_PRECISION_INC
|
||||
#define FRACTAL_PRECISION_INC BUTTON_BOTTOMRIGHT
|
||||
#endif
|
||||
#ifndef FRACTAL_PRECISION_DEC
|
||||
#define FRACTAL_PRECISION_DEC BUTTON_BOTTOMLEFT
|
||||
#endif
|
||||
#ifndef FRACTAL_RESET
|
||||
#define FRACTAL_RESET BUTTON_CENTER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
209
apps/plugins/fractals/fractal_rect.c
Normal file
209
apps/plugins/fractals/fractal_rect.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "fractal_rect.h"
|
||||
|
||||
#define RECT_QUEUE_LEN 32
|
||||
|
||||
#define QUEUE_NEXT(i) (((i) + 1) % RECT_QUEUE_LEN)
|
||||
#define QUEUE_PREV(i) (((i) - 1) % RECT_QUEUE_LEN)
|
||||
#define QUEUE_IS_EMPTY (QUEUE_NEXT(rectq.head) == rectq.tail)
|
||||
#define QUEUE_TAIL \
|
||||
(&rectq.rects[rectq.tail]);
|
||||
#define QUEUE_ITEM(i) &rectq.rects[(i)]
|
||||
|
||||
struct rect_queue
|
||||
{
|
||||
struct fractal_rect rects[RECT_QUEUE_LEN];
|
||||
unsigned head;
|
||||
unsigned tail;
|
||||
};
|
||||
|
||||
static struct rect_queue rectq;
|
||||
|
||||
/*#define FRACTAL_RECT_DEBUG*/
|
||||
#if defined(FRACTAL_RECT_DEBUG) && defined(SIMULATOR)
|
||||
#include <stdio.h>
|
||||
|
||||
static void rectq_print(void)
|
||||
{
|
||||
unsigned i = rectq.head;
|
||||
|
||||
printf("Rects queue:\n");
|
||||
for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV(i))
|
||||
{
|
||||
printf("\tItem %d/%d; idx %d; (%d,%d),(%d,%d),%svalid%s%s\n",
|
||||
(i - rectq.head + 1) % RECT_QUEUE_LEN,
|
||||
(rectq.head - rectq.tail) % RECT_QUEUE_LEN,
|
||||
i,
|
||||
rectq.rects[(i)].px_min,
|
||||
rectq.rects[(i)].py_min,
|
||||
rectq.rects[(i)].px_max,
|
||||
rectq.rects[(i)].py_max,
|
||||
(rectq.rects[(i)].valid ? "" : "in"),
|
||||
((i == rectq.head) ? ",head" : ""),
|
||||
((i == rectq.tail) ? ",tail" : ""));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define rectq_print(...)
|
||||
#endif
|
||||
|
||||
static int rects_add(int px_min, int py_min, int px_max, int py_max)
|
||||
{
|
||||
struct fractal_rect *rect = &rectq.rects[rectq.tail];
|
||||
|
||||
if (rectq.head == QUEUE_PREV(rectq.tail)) /* queue is full */
|
||||
return 1;
|
||||
|
||||
rect->px_min = px_min;
|
||||
rect->py_min = py_min;
|
||||
rect->px_max = px_max;
|
||||
rect->py_max = py_max;
|
||||
rect->valid = 1;
|
||||
rectq.tail = QUEUE_PREV(rectq.tail);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rects_queue_reset(void)
|
||||
{
|
||||
rectq.tail = 0;
|
||||
rectq.head = 0;
|
||||
}
|
||||
|
||||
void rects_queue_init(void)
|
||||
{
|
||||
rects_queue_reset();
|
||||
rects_add(0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
}
|
||||
|
||||
void rects_calc_all(int (*calc)(struct fractal_rect *, int (*)(void *), void *),
|
||||
int (*button_yield_cb)(void *), void *ctx)
|
||||
{
|
||||
while (rectq.head != rectq.tail) /* queue is not empty */
|
||||
{
|
||||
struct fractal_rect *rect = &rectq.rects[rectq.head];
|
||||
|
||||
rectq_print();
|
||||
if (rect->valid)
|
||||
{
|
||||
if (calc(rect, button_yield_cb, ctx))
|
||||
return; /* interrupted by key-press */
|
||||
}
|
||||
|
||||
rectq.head = QUEUE_PREV(rectq.head); /* dequeue */
|
||||
}
|
||||
rects_queue_reset();
|
||||
}
|
||||
|
||||
int rects_move_up(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* move current regions up */
|
||||
for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
|
||||
{
|
||||
struct fractal_rect *rect = QUEUE_ITEM(i);
|
||||
|
||||
rect->py_min -= LCD_SHIFT_Y;
|
||||
rect->py_max -= LCD_SHIFT_Y;
|
||||
|
||||
if (rect->py_min < 0)
|
||||
rect->py_min = 0;
|
||||
|
||||
if (rect->py_max < 0)
|
||||
rect->valid = 0;
|
||||
}
|
||||
|
||||
/* add bottom region */
|
||||
return rects_add(0, LCD_HEIGHT - LCD_SHIFT_Y, LCD_WIDTH, LCD_HEIGHT);
|
||||
}
|
||||
|
||||
int rects_move_down(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* move current regions down */
|
||||
for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
|
||||
{
|
||||
struct fractal_rect *rect = QUEUE_ITEM(i);
|
||||
|
||||
rect->py_min += LCD_SHIFT_Y;
|
||||
rect->py_max += LCD_SHIFT_Y;
|
||||
|
||||
if (rect->py_max > LCD_HEIGHT)
|
||||
rect->py_max = LCD_HEIGHT;
|
||||
|
||||
if (LCD_HEIGHT <= rect->py_min)
|
||||
rect->valid = 0;
|
||||
}
|
||||
|
||||
/* add top region */
|
||||
return rects_add(0, 0, LCD_WIDTH, LCD_SHIFT_Y);
|
||||
}
|
||||
|
||||
int rects_move_left(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* move current regions left */
|
||||
for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
|
||||
{
|
||||
struct fractal_rect *rect = QUEUE_ITEM(i);
|
||||
|
||||
rect->px_min -= LCD_SHIFT_X;
|
||||
rect->px_max -= LCD_SHIFT_X;
|
||||
|
||||
if (rect->px_min < 0)
|
||||
rect->px_min = 0;
|
||||
|
||||
if (rect->px_max < 0)
|
||||
rect->valid = 0;
|
||||
}
|
||||
|
||||
/* add right region */
|
||||
return rects_add(LCD_WIDTH - LCD_SHIFT_X, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
}
|
||||
|
||||
int rects_move_right(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* move current regions right */
|
||||
for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
|
||||
{
|
||||
struct fractal_rect *rect = QUEUE_ITEM(i);
|
||||
|
||||
rect->px_min += LCD_SHIFT_X;
|
||||
rect->px_max += LCD_SHIFT_X;
|
||||
|
||||
if (rect->px_max > LCD_WIDTH)
|
||||
rect->px_max = LCD_WIDTH;
|
||||
|
||||
if (LCD_WIDTH <= rect->px_min)
|
||||
rect->valid = 0;
|
||||
}
|
||||
|
||||
/* add left region */
|
||||
return rects_add(0, 0, LCD_SHIFT_X, LCD_HEIGHT);
|
||||
}
|
||||
|
38
apps/plugins/fractals/fractal_rect.h
Normal file
38
apps/plugins/fractals/fractal_rect.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _FRACTAL_RECT_H
|
||||
#define _FRACTAL_RECT_H
|
||||
|
||||
#include "fractal_sets.h"
|
||||
|
||||
#define LCD_SHIFT_X (LCD_WIDTH / 8)
|
||||
#define LCD_SHIFT_Y (LCD_HEIGHT / 8)
|
||||
|
||||
void rects_queue_init(void);
|
||||
void rects_calc_all(int (*calc)(struct fractal_rect *, int (*)(void *), void *),
|
||||
int (*button_yield_cb)(void *), void *ctx);
|
||||
int rects_move_up(void);
|
||||
int rects_move_down(void);
|
||||
int rects_move_left(void);
|
||||
int rects_move_right(void);
|
||||
|
||||
#endif
|
||||
|
52
apps/plugins/fractals/fractal_sets.h
Normal file
52
apps/plugins/fractals/fractal_sets.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _FRACTAL_SETS_H
|
||||
#define _FRACTAL_SETS_H
|
||||
|
||||
#include "lib/grey.h"
|
||||
#include "lib/xlcd.h"
|
||||
|
||||
#ifdef USEGSLIB
|
||||
extern unsigned char imgbuffer[LCD_HEIGHT];
|
||||
#else
|
||||
extern fb_data imgbuffer[LCD_HEIGHT];
|
||||
#endif
|
||||
|
||||
struct fractal_rect
|
||||
{
|
||||
int px_min;
|
||||
int py_min;
|
||||
int px_max;
|
||||
int py_max;
|
||||
int valid;
|
||||
};
|
||||
|
||||
struct fractal_ops
|
||||
{
|
||||
void (*init)(void);
|
||||
int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx),
|
||||
void *button_yield_ctx);
|
||||
void (*move)(int dx, int dy);
|
||||
void (*zoom)(int factor);
|
||||
int (*precision)(int d);
|
||||
};
|
||||
|
||||
#endif
|
21
apps/plugins/fractals/fractals.make
Normal file
21
apps/plugins/fractals/fractals.make
Normal file
|
@ -0,0 +1,21 @@
|
|||
# __________ __ ___.
|
||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
# \/ \/ \/ \/ \/
|
||||
# $Id$
|
||||
#
|
||||
|
||||
FRACTALSSRCDIR := $(APPSDIR)/plugins/fractals
|
||||
FRACTALSBUILDDIR := $(BUILDDIR)/apps/plugins/fractals
|
||||
|
||||
ROCKS += $(FRACTALSBUILDDIR)/fractals.rock
|
||||
|
||||
FRACTALS_SRC := $(call preprocess, $(FRACTALSSRCDIR)/SOURCES)
|
||||
FRACTALS_OBJ := $(call c2obj, $(FRACTALS_SRC))
|
||||
|
||||
# add source files to OTHER_SRC to get automatic dependencies
|
||||
OTHER_SRC += $(FRACTALS_SRC)
|
||||
|
||||
$(FRACTALSBUILDDIR)/fractals.rock: $(FRACTALS_OBJ)
|
392
apps/plugins/fractals/mandelbrot_set.c
Normal file
392
apps/plugins/fractals/mandelbrot_set.c
Normal file
|
@ -0,0 +1,392 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: mandelbrot.c 24010 2009-12-15 20:51:41Z tomers $
|
||||
*
|
||||
* Copyright (C) 2004 Matthias Wientapper
|
||||
* Heavily extended 2005 Jens Arnold
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "mandelbrot_set.h"
|
||||
|
||||
#define BUTTON_YIELD_TIMEOUT (HZ / 4)
|
||||
|
||||
/* 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 unsigned char color[9] = {
|
||||
255, 223, 191, 159, 128, 96, 64, 32, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_LCD == LCD_SSD1815
|
||||
/* Recorder, Ondio: pixel_height == 1.25 * pixel_width */
|
||||
#define MB_HEIGHT (LCD_HEIGHT*5/4)
|
||||
#else
|
||||
/* square pixels */
|
||||
#define MB_HEIGHT LCD_HEIGHT
|
||||
#endif
|
||||
|
||||
#define MB_XOFS (-0x03000000L) /* -0.75 (s5.26) */
|
||||
#if 3000*MB_HEIGHT/LCD_WIDTH >= 2400 /* width is limiting factor */
|
||||
#define MB_XFAC (0x06000000LL) /* 1.5 (s5.26) */
|
||||
#define MB_YFAC (MB_XFAC*MB_HEIGHT/LCD_WIDTH)
|
||||
#else /* height is limiting factor */
|
||||
#define MB_YFAC (0x04cccccdLL) /* 1.2 (s5.26) */
|
||||
#define MB_XFAC (MB_YFAC*LCD_WIDTH/MB_HEIGHT)
|
||||
#endif
|
||||
|
||||
#if (LCD_DEPTH < 8)
|
||||
#else
|
||||
#define UPDATE_FREQ (HZ/50)
|
||||
#endif
|
||||
|
||||
/* Fixed point format s5.26: sign, 5 bits integer part, 26 bits fractional part */
|
||||
struct mandelbrot_ctx
|
||||
{
|
||||
struct fractal_ops *ops;
|
||||
long x_min;
|
||||
long x_max;
|
||||
long x_step;
|
||||
long x_delta;
|
||||
long y_min;
|
||||
long y_max;
|
||||
long y_step;
|
||||
long y_delta;
|
||||
int step_log2;
|
||||
unsigned max_iter;
|
||||
} ctx;
|
||||
|
||||
static void mandelbrot_init(void);
|
||||
|
||||
static int mandelbrot_calc_low_prec(struct fractal_rect *rect,
|
||||
int (*button_yield_cb)(void *), void *button_yield_ctx);
|
||||
|
||||
static int mandelbrot_calc_high_prec(struct fractal_rect *rect,
|
||||
int (*button_yield_cb)(void *), void *button_yield_ctx);
|
||||
|
||||
static void mandelbrot_move(int dx, int dy);
|
||||
|
||||
static void mandelbrot_zoom(int factor);
|
||||
|
||||
static int mandelbrot_precision(int d);
|
||||
|
||||
struct fractal_ops mandelbrot_ops =
|
||||
{
|
||||
.init = mandelbrot_init,
|
||||
.calc = NULL,
|
||||
.move = mandelbrot_move,
|
||||
.zoom = mandelbrot_zoom,
|
||||
.precision = mandelbrot_precision,
|
||||
};
|
||||
|
||||
static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (value <= 0)
|
||||
{
|
||||
return -32767;
|
||||
}
|
||||
else if (value > (1L << 26))
|
||||
{
|
||||
while (value >= (2L << 26))
|
||||
{
|
||||
value >>= 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (value < (1L<<26))
|
||||
{
|
||||
value <<= 1;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static void recalc_parameters(void)
|
||||
{
|
||||
ctx.x_step = (ctx.x_max - ctx.x_min) / LCD_WIDTH;
|
||||
ctx.x_delta = (ctx.x_step * LCD_WIDTH) / 8;
|
||||
ctx.y_step = (ctx.y_max - ctx.y_min) / LCD_HEIGHT;
|
||||
ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8;
|
||||
ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step));
|
||||
ctx.max_iter = MAX(15, -15 * ctx.step_log2 - 45);
|
||||
|
||||
ctx.ops->calc = (ctx.step_log2 <= -10) ?
|
||||
mandelbrot_calc_high_prec : mandelbrot_calc_low_prec;
|
||||
}
|
||||
|
||||
static void mandelbrot_init(void)
|
||||
{
|
||||
ctx.ops = &mandelbrot_ops;
|
||||
|
||||
ctx.x_min = MB_XOFS - MB_XFAC;
|
||||
ctx.x_max = MB_XOFS + MB_XFAC;
|
||||
ctx.y_min = -MB_YFAC;
|
||||
ctx.y_max = MB_YFAC;
|
||||
|
||||
recalc_parameters();
|
||||
}
|
||||
|
||||
static int mandelbrot_calc_low_prec(struct fractal_rect *rect,
|
||||
int (*button_yield_cb)(void *), void *button_yield_ctx)
|
||||
{
|
||||
#ifndef USEGSLIB
|
||||
long next_update = *rb->current_tick;
|
||||
int last_px = rect->px_min;
|
||||
#endif
|
||||
unsigned n_iter;
|
||||
long a32, b32;
|
||||
short x, x2, y, y2, a, b;
|
||||
int p_x, p_y;
|
||||
unsigned long last_yield = *rb->current_tick;
|
||||
unsigned long last_button_yield = *rb->current_tick;
|
||||
|
||||
a32 = ctx.x_min + ctx.x_step * rect->px_min;
|
||||
|
||||
for (p_x = rect->px_min; p_x < rect->px_max; p_x++)
|
||||
{
|
||||
a = a32 >> 16;
|
||||
|
||||
b32 = ctx.y_min + ctx.y_step * (LCD_HEIGHT - rect->py_max);
|
||||
|
||||
for (p_y = rect->py_max - 1; p_y >= rect->py_min; p_y--)
|
||||
{
|
||||
b = b32 >> 16;
|
||||
x = a;
|
||||
y = b;
|
||||
n_iter = 0;
|
||||
|
||||
while (++n_iter <= ctx.max_iter)
|
||||
{
|
||||
x2 = MULS16_ASR10(x, x);
|
||||
y2 = MULS16_ASR10(y, y);
|
||||
|
||||
if (x2 + y2 > (4<<10)) break;
|
||||
|
||||
y = 2 * MULS16_ASR10(x, y) + b;
|
||||
x = x2 - y2 + a;
|
||||
}
|
||||
|
||||
if (n_iter > ctx.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 (TIME_AFTER(*rb->current_tick, last_yield))
|
||||
{
|
||||
rb->yield();
|
||||
last_yield = *rb->current_tick;
|
||||
}
|
||||
|
||||
if (TIME_AFTER(*rb->current_tick, last_button_yield))
|
||||
{
|
||||
if (button_yield_cb(button_yield_ctx))
|
||||
{
|
||||
#ifndef USEGSLIB
|
||||
/* update screen part that was changed since last yield */
|
||||
rb->lcd_update_rect(last_px, rect->py_min,
|
||||
p_x - last_px + 1, rect->py_max - rect->py_min);
|
||||
#endif
|
||||
rect->px_min = (p_x == 0) ? 0 : p_x - 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
last_button_yield = *rb->current_tick + BUTTON_YIELD_TIMEOUT;
|
||||
}
|
||||
|
||||
b32 += ctx.y_step;
|
||||
}
|
||||
#ifdef USEGSLIB
|
||||
grey_ub_gray_bitmap_part(imgbuffer, 0, rect->py_min, 1,
|
||||
p_x, rect->py_min, 1, rect->py_max - rect->py_min);
|
||||
#else
|
||||
rb->lcd_bitmap_part(imgbuffer, 0, rect->py_min, 1,
|
||||
p_x, rect->py_min, 1, rect->py_max - rect->py_min);
|
||||
|
||||
if ((p_x == rect->px_max - 1) ||
|
||||
TIME_AFTER(*rb->current_tick, next_update))
|
||||
{
|
||||
next_update = *rb->current_tick + UPDATE_FREQ;
|
||||
|
||||
/* update screen part that was changed since last yield */
|
||||
rb->lcd_update_rect(last_px, rect->py_min,
|
||||
p_x - last_px + 1, rect->py_max - rect->py_min);
|
||||
last_px = p_x;
|
||||
}
|
||||
#endif
|
||||
|
||||
a32 += ctx.x_step;
|
||||
}
|
||||
|
||||
rect->valid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mandelbrot_calc_high_prec(struct fractal_rect *rect,
|
||||
int (*button_yield_cb)(void *), void *button_yield_ctx)
|
||||
{
|
||||
#ifndef USEGSLIB
|
||||
long next_update = *rb->current_tick;
|
||||
int last_px = rect->px_min;
|
||||
#endif
|
||||
unsigned n_iter;
|
||||
long x, x2, y, y2, a, b;
|
||||
int p_x, p_y;
|
||||
unsigned long last_yield = *rb->current_tick;
|
||||
unsigned long last_button_yield = *rb->current_tick;
|
||||
|
||||
MULS32_INIT();
|
||||
|
||||
a = ctx.x_min + ctx.x_step * rect->px_min;
|
||||
|
||||
for (p_x = rect->px_min; p_x < rect->px_max; p_x++)
|
||||
{
|
||||
b = ctx.y_min + ctx.y_step * (LCD_HEIGHT - rect->py_max);
|
||||
|
||||
for (p_y = rect->py_max - 1; p_y >= rect->py_min; p_y--)
|
||||
{
|
||||
x = a;
|
||||
y = b;
|
||||
n_iter = 0;
|
||||
|
||||
while (++n_iter <= ctx.max_iter)
|
||||
{
|
||||
x2 = MULS32_ASR26(x, x);
|
||||
y2 = MULS32_ASR26(y, y);
|
||||
|
||||
if (x2 + y2 > (4L<<26)) break;
|
||||
|
||||
y = 2 * MULS32_ASR26(x, y) + b;
|
||||
x = x2 - y2 + a;
|
||||
}
|
||||
|
||||
if (n_iter > ctx.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 (TIME_AFTER(*rb->current_tick, last_yield))
|
||||
{
|
||||
rb->yield();
|
||||
last_yield = *rb->current_tick;
|
||||
}
|
||||
|
||||
if (TIME_AFTER(*rb->current_tick, last_button_yield))
|
||||
{
|
||||
if (button_yield_cb(button_yield_ctx))
|
||||
{
|
||||
#ifndef USEGSLIB
|
||||
/* update screen part that was changed since last yield */
|
||||
rb->lcd_update_rect(last_px, rect->py_min,
|
||||
p_x - last_px + 1, rect->py_max - rect->py_min);
|
||||
#endif
|
||||
rect->px_min = (p_x == 0) ? 0 : p_x - 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
last_button_yield = *rb->current_tick + BUTTON_YIELD_TIMEOUT;
|
||||
}
|
||||
|
||||
b += ctx.y_step;
|
||||
}
|
||||
#ifdef USEGSLIB
|
||||
grey_ub_gray_bitmap_part(imgbuffer, 0, rect->py_min, 1,
|
||||
p_x, rect->py_min, 1, rect->py_max - rect->py_min);
|
||||
#else
|
||||
rb->lcd_bitmap_part(imgbuffer, 0, rect->py_min, 1,
|
||||
p_x, rect->py_min, 1, rect->py_max - rect->py_min);
|
||||
|
||||
if ((p_x == rect->px_max - 1) ||
|
||||
TIME_AFTER(*rb->current_tick, next_update))
|
||||
{
|
||||
next_update = *rb->current_tick + UPDATE_FREQ;
|
||||
|
||||
/* update screen part that was changed since last yield */
|
||||
rb->lcd_update_rect(last_px, rect->py_min,
|
||||
p_x - last_px + 1, rect->py_max - rect->py_min);
|
||||
last_px = p_x;
|
||||
}
|
||||
#endif
|
||||
a += ctx.x_step;
|
||||
}
|
||||
|
||||
rect->valid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mandelbrot_move(int dx, int dy)
|
||||
{
|
||||
long d_x = (long)dx * ctx.x_delta;
|
||||
long d_y = (long)dy * ctx.y_delta;
|
||||
|
||||
ctx.x_min += d_x;
|
||||
ctx.x_max += d_x;
|
||||
ctx.y_min += d_y;
|
||||
ctx.y_max += d_y;
|
||||
}
|
||||
|
||||
static void mandelbrot_zoom(int factor)
|
||||
{
|
||||
long factor_x = (long)factor * ctx.x_delta;
|
||||
long factor_y = (long)factor * ctx.y_delta;
|
||||
|
||||
ctx.x_min += factor_x;
|
||||
ctx.x_max -= factor_x;
|
||||
ctx.y_min += factor_y;
|
||||
ctx.y_max -= factor_y;
|
||||
|
||||
recalc_parameters();
|
||||
}
|
||||
|
||||
static int mandelbrot_precision(int d)
|
||||
{
|
||||
int changed = 0;
|
||||
|
||||
/* Precision increase */
|
||||
for (; d > 0; d--)
|
||||
{
|
||||
ctx.max_iter += ctx.max_iter / 2;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
/* Precision decrease */
|
||||
for (; d < 0 && ctx.max_iter >= 15; d++)
|
||||
{
|
||||
ctx.max_iter -= ctx.max_iter / 3;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
60
apps/plugins/fractals/mandelbrot_set.h
Normal file
60
apps/plugins/fractals/mandelbrot_set.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2009 Tomer Shalev
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef _MANDELBROT_SET_H
|
||||
#define _MANDELBROT_SET_H
|
||||
|
||||
#include "fractal_sets.h"
|
||||
|
||||
/* CPU stuff */
|
||||
#if CONFIG_CPU == SH7034
|
||||
#include "cpu_sh7043.h"
|
||||
#elif defined CPU_COLDFIRE
|
||||
#include "cpu_coldfire.h"
|
||||
#elif defined CPU_ARM
|
||||
#include "cpu_arm.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_CPU == SH7034
|
||||
#define MULS16_ASR10(a, b) muls16_asr10(a, b)
|
||||
#define MULS32_ASR26(a, b) muls32_asr26(a, b)
|
||||
#elif defined CPU_COLDFIRE
|
||||
/* Needs the EMAC initialised to fractional mode w/o rounding and saturation */
|
||||
#define MULS32_INIT() coldfire_set_macsr(EMAC_FRACTIONAL)
|
||||
#define MULS16_ASR10(a, b) muls16_asr10(a, b)
|
||||
#define MULS32_ASR26(a, b) muls32_asr26(a, b)
|
||||
#elif defined CPU_ARM
|
||||
#define MULS32_ASR26(a, b) muls32_asr26(a, b)
|
||||
#endif
|
||||
|
||||
/* default macros */
|
||||
#ifndef MULS16_ASR10
|
||||
#define MULS16_ASR10(a, b) ((short)(((long)(a) * (long)(b)) >> 10))
|
||||
#endif
|
||||
#ifndef MULS32_ASR26
|
||||
#define MULS32_ASR26(a, b) ((long)(((long long)(a) * (long long)(b)) >> 26))
|
||||
#endif
|
||||
#ifndef MULS32_INIT
|
||||
#define MULS32_INIT()
|
||||
#endif
|
||||
|
||||
extern struct fractal_ops mandelbrot_ops;
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
\subsection{Mandelbrot}
|
||||
\subsection{Fractals}
|
||||
\screenshot{plugins/images/ss-mandelbrot}{Mandelbrot}{img:mandelbrot}
|
||||
This demonstration draws fractal images from the Mandelbrot set
|
||||
\opt{archos,iriverh100}{using the greyscale engine}.
|
|
@ -102,9 +102,9 @@ text files%
|
|||
|
||||
\opt{lcd_bitmap}{\input{plugins/fire.tex}}
|
||||
|
||||
{\input{plugins/logo.tex}}
|
||||
\opt{lcd_bitmap}{\input{plugins/fractals.tex}}
|
||||
|
||||
\opt{lcd_bitmap}{\input{plugins/mandelbrot.tex}}
|
||||
{\input{plugins/logo.tex}}
|
||||
|
||||
{\input{plugins/mosaic.tex}}
|
||||
|
||||
|
|
Loading…
Reference in a new issue