diff options
author | Tomer Shalev <shalev.tomer@gmail.com> | 2010-01-15 05:53:15 +0000 |
---|---|---|
committer | Tomer Shalev <shalev.tomer@gmail.com> | 2010-01-15 05:53:15 +0000 |
commit | 7719d297f2a1da0e45fd39cad21e99e23fd695c8 (patch) | |
tree | ae2b97d1b372340627ca3537554cd45310bace92 /apps/plugins/fractals/fractal.c | |
parent | 51630cbac1dcb04345fb1384812f1576f0ea29db (diff) |
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
Diffstat (limited to 'apps/plugins/fractals/fractal.c')
-rw-r--r-- | apps/plugins/fractals/fractal.c | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/apps/plugins/fractals/fractal.c b/apps/plugins/fractals/fractal.c new file mode 100644 index 0000000000..3a0c785bdd --- /dev/null +++ b/apps/plugins/fractals/fractal.c @@ -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 |