summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-10-07 22:22:07 +0000
committerJens Arnold <amiconn@rockbox.org>2005-10-07 22:22:07 +0000
commitf23ab031a1206d965a38d5051f723d95087d78ea (patch)
treef222f881d9da5f8269b8b6a53e5fae46b88c339f
parentbec86d7b9271a8f1a57373e90a0ef201bcdbfce7 (diff)
New demo plugin, screensaver style, by Kevin Ferrare.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7594 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/demystify.c351
2 files changed, 352 insertions, 0 deletions
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 3f0d377423..a9b7391745 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -21,6 +21,7 @@ dict.c
bounce.c
calculator.c
chip8.c
+demystify.c
fire.c
flipit.c
grayscale.c
diff --git a/apps/plugins/demystify.c b/apps/plugins/demystify.c
new file mode 100644
index 0000000000..9a8027f2ca
--- /dev/null
+++ b/apps/plugins/demystify.c
@@ -0,0 +1,351 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2005 Kevin Ferrare
+*
+* Mystify demo plugin
+*
+* 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.
+*
+* 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
+
+/* Key assignement */
+#define DEMYSTIFY_QUIT BUTTON_OFF
+#define DEMYSTIFY_ADD_POLYGON BUTTON_UP
+#define DEMYSTIFY_REMOVE_POLYGON BUTTON_DOWN
+#define DEMYSTIFY_INCREASE_SPEED BUTTON_RIGHT
+#define DEMYSTIFY_DECREASE_SPEED BUTTON_LEFT
+
+
+#define DEFAULT_WAIT_TIME 3
+#define DEFAULT_NB_POLYGONS 7
+#define NB_POINTS 4
+#define MAX_STEP_RANGE 7
+#define MIN_STEP_RANGE 3
+#define MAX_POLYGONS 40
+#define MIN_POLYGONS 1
+
+/******************************* Globals ***********************************/
+
+static struct plugin_api* rb; /* global api struct pointer */
+
+/*
+ * Compute a new random step to make the point bounce the borders of the screen
+ */
+
+int get_new_step(int step)
+{
+ if(step>0)
+ return -(MIN_STEP_RANGE + rb->rand() % (MAX_STEP_RANGE-MIN_STEP_RANGE));
+ else
+ return (MIN_STEP_RANGE + rb->rand() % (MAX_STEP_RANGE-MIN_STEP_RANGE));
+}
+
+/*
+ * Point Stuffs
+ */
+
+struct point
+{
+ int x;
+ int y;
+};
+
+/*
+ * Polygon Stuffs
+ */
+
+struct polygon
+{
+ struct point points[NB_POINTS];
+};
+
+/*
+ * Generates a random polygon (which fits the screen size though)
+ */
+void polygon_init(struct polygon * polygon)
+{
+ int i;
+ for(i=0;i<NB_POINTS;++i)
+ {
+ polygon->points[i].x=(rb->rand() % (LCD_WIDTH));
+ polygon->points[i].y=(rb->rand() % (LCD_HEIGHT));
+ }
+}
+
+/*
+ * Draw the given polygon onto the screen
+ */
+
+void polygon_draw(struct polygon * polygon)
+{
+ int i;
+ for(i=0;i<NB_POINTS-1;++i)
+ {
+ rb->lcd_drawline(polygon->points[i].x, polygon->points[i].y,
+ polygon->points[i+1].x, polygon->points[i+1].y);
+ }
+ rb->lcd_drawline(polygon->points[0].x, polygon->points[0].y,
+ polygon->points[NB_POINTS-1].x,
+ polygon->points[NB_POINTS-1].y);
+}
+
+/*
+ * Polygon moving data Stuffs
+ */
+
+struct polygon_move
+{
+ struct point move_steps[NB_POINTS];
+};
+
+void polygon_move_init(struct polygon_move * polygon_move)
+{
+ int i;
+ for(i=0;i<NB_POINTS;++i)
+ {
+ polygon_move->move_steps[i].x=get_new_step(-1);
+ /* -1 because we want a positive random step */
+ polygon_move->move_steps[i].y=get_new_step(-1);
+ }
+}
+
+/*
+ * Update the given polygon's position according to the given informations in
+ * polygon_move (polygon_move may be updated)
+ */
+void polygon_update(struct polygon *polygon, struct polygon_move *polygon_move)
+{
+ int i, x, y, step;
+ for(i=0;i<NB_POINTS;++i)
+ {
+ x=polygon->points[i].x;
+ step=polygon_move->move_steps[i].x;
+ x+=step;
+ if(x<=0)
+ {
+ x=1;
+ polygon_move->move_steps[i].x=get_new_step(step);
+ }
+ else if(x>=LCD_WIDTH)
+ {
+ x=LCD_WIDTH-1;
+ polygon_move->move_steps[i].x=get_new_step(step);
+ }
+ polygon->points[i].x=x;
+
+ y=polygon->points[i].y;
+ step=polygon_move->move_steps[i].y;
+ y+=step;
+ if(y<=0)
+ {
+ y=1;
+ polygon_move->move_steps[i].y=get_new_step(step);
+ }
+ else if(y>=LCD_HEIGHT)
+ {
+ y=LCD_HEIGHT-1;
+ polygon_move->move_steps[i].y=get_new_step(step);
+ }
+ polygon->points[i].y=y;
+ }
+}
+
+/*
+ * Polygon fifo Stuffs
+ */
+
+struct polygon_fifo
+{
+ int fifo_tail;
+ int fifo_head;
+ int nb_items;
+ struct polygon tab[MAX_POLYGONS];
+};
+
+void fifo_init(struct polygon_fifo * fifo)
+{
+ fifo->fifo_tail=0;
+ fifo->fifo_head=0;
+ fifo->nb_items=0;
+}
+
+void fifo_push(struct polygon_fifo * fifo, struct polygon * polygon)
+{
+ if(fifo->nb_items>=MAX_POLYGONS)
+ return;
+ ++(fifo->nb_items);
+
+ /*
+ * Workaround for gcc (which uses memcpy internally) to avoid link error
+ * fifo->tab[fifo->fifo_head]=polygon
+ */
+ rb->memcpy(&(fifo->tab[fifo->fifo_head]), polygon, sizeof(struct polygon));
+ ++(fifo->fifo_head);
+ if(fifo->fifo_head>=MAX_POLYGONS)
+ fifo->fifo_head=0;
+}
+
+struct polygon * fifo_pop(struct polygon_fifo * fifo)
+{
+ int index;
+ if(fifo->nb_items==0)
+ return(NULL);
+ --(fifo->nb_items);
+ index=fifo->fifo_tail;
+ ++(fifo->fifo_tail);
+ if(fifo->fifo_tail>=MAX_POLYGONS)
+ fifo->fifo_tail=0;
+ return(&(fifo->tab[index]));
+}
+
+/*
+ * Drawing stuffs
+ */
+
+void polygons_draw(struct polygon_fifo * polygons)
+{
+ int i, j;
+ for(i=0, j=polygons->fifo_tail;i<polygons->nb_items;++i, ++j)
+ {
+ if(j>=MAX_POLYGONS)
+ j=0;
+ polygon_draw(&(polygons->tab[j]));
+ }
+}
+
+
+
+static struct polygon_fifo polygons;
+static struct polygon_move move; /* This describes the movement of the leading
+ polygon, the others just follow */
+static struct polygon leading_polygon;
+
+
+void cleanup(void *parameter)
+{
+ (void)parameter;
+
+ rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
+}
+
+/*
+ * Main function
+ */
+
+int plugin_main(void)
+{
+ int button;
+ int sleep_time=DEFAULT_WAIT_TIME;
+ int nb_wanted_polygons=DEFAULT_NB_POLYGONS;
+
+ fifo_init(&polygons);
+ polygon_move_init(&move);
+ polygon_init(&leading_polygon);
+
+ while (true)
+ {
+ if(polygons.nb_items>nb_wanted_polygons)
+ { /* We have too many polygons, we must drop some of them */
+ fifo_pop(&polygons);
+ }
+ if(nb_wanted_polygons==polygons.nb_items)
+ { /* We have the good number of polygons, we can safely drop the last
+ one to add the new one later */
+ fifo_pop(&polygons);
+ }
+ fifo_push(&polygons, &leading_polygon);
+
+ /*
+ * Then we update the leading polygon for the next round acording to
+ * current move (the move may be altered in case of sreen border
+ * collision)
+ */
+ polygon_update(&leading_polygon, &move);
+
+ /* Now the drawing part */
+
+ rb->lcd_clear_display();
+ polygons_draw(&polygons);
+ rb->lcd_update();
+
+ /* Speed handling*/
+ if (sleep_time<0)/* full speed */
+ rb->yield();
+ else
+ rb->sleep(sleep_time);
+
+ /* Handle the user events */
+ button = rb->button_get(false);
+ switch(button)
+ {
+ case (DEMYSTIFY_QUIT):
+ cleanup(NULL);
+ return PLUGIN_OK;
+
+ case (DEMYSTIFY_ADD_POLYGON):
+ if(nb_wanted_polygons<MAX_POLYGONS)
+ ++nb_wanted_polygons;
+ break;
+
+ case (DEMYSTIFY_REMOVE_POLYGON):
+ if(nb_wanted_polygons>MIN_POLYGONS)
+ --nb_wanted_polygons;
+ break;
+
+ case (DEMYSTIFY_INCREASE_SPEED):
+ if(sleep_time>=0)
+ --sleep_time;
+ break;
+
+ case (DEMYSTIFY_DECREASE_SPEED):
+ ++sleep_time;
+ break;
+
+ default:
+ if (rb->default_event_handler_ex(button, cleanup, NULL)
+ == SYS_USB_CONNECTED)
+ return PLUGIN_USB_CONNECTED;
+ break;
+ }
+ }
+}
+
+/*************************** Plugin entry point ****************************/
+
+enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+{
+ int ret;
+ /*
+ * this macro should be called as the first thing you do in the plugin.
+ * it test that the api version and model the plugin was compiled for
+ * matches the machine it is running on
+ */
+
+ TEST_PLUGIN_API(api);
+
+ rb = api; /* copy to global api pointer */
+ (void)parameter;
+ if (rb->global_settings->backlight_timeout > 0)
+ rb->backlight_set_timeout(1);/* keep the light on */
+
+ ret = plugin_main();
+
+ return ret;
+}
+
+#endif /* #ifdef HAVE_LCD_BITMAP */