diff options
Diffstat (limited to 'hacks/spiral.c')
-rw-r--r-- | hacks/spiral.c | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/hacks/spiral.c b/hacks/spiral.c new file mode 100644 index 0000000..3d8159b --- /dev/null +++ b/hacks/spiral.c @@ -0,0 +1,330 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* spiral --- spiraling dots */ + +#if 0 +static const char sccsid[] = "@(#)spiral.c 5.00 2000/11/01 xlockmore"; +#endif + +/*- + * Copyright (c) 1994 by Darrick Brown. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 10-May-1997: jwz@jwz.org: turned into a standalone program. + * 24-Jul-1995: Fix to allow cycles not to have an arbitrary value by + * Peter Schmitzberger (schmitz@coma.sbg.ac.at). + * 06-Mar-1995: Finished cleaning up and final testing. + * 03-Mar-1995: Cleaned up code. + * 12-Jul-1994: Written. + * + * Low CPU usage mode. + * Idea based on a graphics demo I saw a *LONG* time ago. + */ + +#ifdef STANDALONE +# define MODE_spiral +#define DEFAULTS "*delay: 50000 \n" \ + "*count: 40 \n" \ + "*cycles: 350 \n" \ + "*ncolors: 64 \n" \ + "*fpsSolid: true \n" \ + +# define SMOOTH_COLORS +# define release_spiral 0 +# define reshape_spiral 0 +# define spiral_handle_event 0 +# include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +# include "xlock.h" /* from the xlockmore distribution */ +#endif /* !STANDALONE */ + +#ifdef MODE_spiral + +ENTRYPOINT ModeSpecOpt spiral_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct spiral_description = +{"spiral", "init_spiral", "draw_spiral", (char *) NULL, + "refresh_spiral", "init_spiral", "free_spiral", &spiral_opts, + 5000, -40, 350, 1, 64, 1.0, "", + "Shows a helical locus of points", 0, NULL}; + +#endif + +#define MAXTRAIL 512 /* The length of the trail */ +#define MAXDOTS 40 +#define MINDOTS 1 +#define TWOPI (2.0*M_PI) /* for convienence */ +#define JAGGINESS 4 /* This sets the "Craziness" of the spiral (I like 4) */ +#define SPEED 2.0 + +/* How many segments to draw per cycle when redrawing */ +#define REDRAWSTEP 3 + + +typedef struct { + float hx, hy, ha, hr; +} Traildots; + +typedef struct { + Traildots *traildots; + float cx, cy; + float angle; + float radius; + float dr, da; + float dx, dy; + int erase; + int inc; + float colors; + int width, height; + float top, bottom, left, right; + int dots, nlength; + int redrawing, redrawpos; +} spiralstruct; + +static spiralstruct *spirals = (spiralstruct *) NULL; + +static void draw_dots(ModeInfo * mi, int in); + +#define TFX(sp,x) ((int)((x/sp->right)*(float)sp->width)) +#define TFY(sp,y) ((int)((y/sp->top)*(float)sp->height)) + +static void +draw_dots(ModeInfo * mi, int in) +{ + + float i, inc; + float x, y; + + spiralstruct *sp = &spirals[MI_SCREEN(mi)]; + + inc = TWOPI / (float) sp->dots; + for (i = 0.0; i < TWOPI; i += inc) { + x = sp->traildots[in].hx + COSF(i + sp->traildots[in].ha) * + sp->traildots[in].hr; + y = sp->traildots[in].hy + SINF(i + sp->traildots[in].ha) * + sp->traildots[in].hr; + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), + TFX(sp, x), TFY(sp, y)); + } +} + +ENTRYPOINT void +init_spiral(ModeInfo * mi) +{ + spiralstruct *sp; + int i; + + MI_INIT (mi, spirals); + sp = &spirals[MI_SCREEN(mi)]; + +#ifdef HAVE_JWXYZ + jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False); +#endif + + sp->width = MI_WIDTH(mi); + sp->height = MI_HEIGHT(mi); + + MI_CLEARWINDOW(mi); + + /* Init */ + sp->nlength = MI_CYCLES(mi); + + if (!sp->traildots) + if ((sp->traildots = (Traildots *) malloc(sp->nlength * + sizeof (Traildots))) == NULL) { + return; + } + + /* initialize the allocated array */ + for (i = 0; i < sp->nlength; i++) { + sp->traildots[i].hx = 0.0; + sp->traildots[i].hy = 0.0; + sp->traildots[i].ha = 0.0; + sp->traildots[i].hr = 0.0; + } + sp->redrawing = 0; + + /* keep the window parameters proportional */ + sp->top = 10000.0; + sp->bottom = 0; + sp->right = (float) (sp->width) / (float) (sp->height) * (10000.0); + sp->left = 0; + + /* assign the initial values */ + sp->cx = (float) (5000.0 - NRAND(2000)) / 10000.0 * sp->right; + sp->cy = (float) (5000.0 - NRAND(2000)); + sp->radius = (float) (NRAND(200) + 200); + sp->angle = 0.0; + sp->dx = (float) (10 - NRAND(20)) * SPEED; + sp->dy = (float) (10 - NRAND(20)) * SPEED; + sp->dr = (float) ((NRAND(10) + 4) * (1 - (LRAND() & 1) * 2)); + sp->da = (float) NRAND(360) / 7200.0 + 0.01; + if (MI_NPIXELS(mi) > 2) + sp->colors = (float) NRAND(MI_NPIXELS(mi)); + sp->erase = 0; + sp->inc = 0; + sp->traildots[sp->inc].hx = sp->cx; + sp->traildots[sp->inc].hy = sp->cy; + sp->traildots[sp->inc].ha = sp->angle; + sp->traildots[sp->inc].hr = sp->radius; + sp->inc++; + + sp->dots = MI_COUNT(mi); + if (sp->dots < -MINDOTS) + sp->dots = NRAND(sp->dots - MINDOTS + 1) + MINDOTS; + /* Absolute minimum */ + if (sp->dots < MINDOTS) + sp->dots = MINDOTS; +} + +ENTRYPOINT void +draw_spiral(ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + GC gc = MI_GC(mi); + int i, j; + spiralstruct *sp; + + if (spirals == NULL) + return; + sp = &spirals[MI_SCREEN(mi)]; + if (sp->traildots == NULL) + return; + + MI_IS_DRAWN(mi) = True; + if (sp->erase == 1) { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + draw_dots(mi, sp->inc); + } + sp->cx += sp->dx; + sp->traildots[sp->inc].hx = sp->cx; + + if ((sp->cx > 9000.0) || (sp->cx < 1000.0)) + sp->dx *= -1.0; + + sp->cy += sp->dy; + sp->traildots[sp->inc].hy = sp->cy; + + if ((sp->cy > 9000.0) || (sp->cy < 1000.0)) + sp->dy *= -1.0; + + sp->radius += sp->dr; + sp->traildots[sp->inc].hr = sp->radius; + + if ((sp->radius > 2500.0) && (sp->dr > 0.0)) + sp->dr *= -1.0; + else if ((sp->radius < 50.0) && (sp->radius < 0.0)) + sp->dr *= -1.0; + + /* Randomly give some variations to: */ + + /* spiral direction (if it is within the boundaries) */ + if ((NRAND(3000) < 1 * JAGGINESS) && + (((sp->cx > 2000.0) && (sp->cx < 8000.0)) && + ((sp->cy > 2000.0) && (sp->cy < 8000.0)))) { + sp->dx = (float) (10 - NRAND(20)) * SPEED; + sp->dy = (float) (10 - NRAND(20)) * SPEED; + } + /* The speed of the change in size of the spiral */ + if (NRAND(3000) < 1 * JAGGINESS) { + if (LRAND() & 1) + sp->dr += (float) (NRAND(3) + 1); + else + sp->dr -= (float) (NRAND(3) + 1); + + /* don't let it get too wild */ + if (sp->dr > 18.0) + sp->dr = 18.0; + else if (sp->dr < 4.0) + sp->dr = 4.0; + } + /* The speed of rotation */ + if (NRAND(3000) < 1 * JAGGINESS) + sp->da = (float) NRAND(360) / 7200.0 + 0.01; + + /* Reverse rotation */ + if (NRAND(3000) < 1 * JAGGINESS) + sp->da *= -1.0; + + sp->angle += sp->da; + sp->traildots[sp->inc].ha = sp->angle; + + if (sp->angle > TWOPI) + sp->angle -= TWOPI; + else if (sp->angle < 0.0) + sp->angle += TWOPI; + + sp->colors += (float) MI_NPIXELS(mi) / ((float) (2 * sp->nlength)); + if (sp->colors >= (float) MI_NPIXELS(mi)) + sp->colors = 0.0; + + if (MI_NPIXELS(mi) > 2) + XSetForeground(display, gc, MI_PIXEL(mi, (int) sp->colors)); + else + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + draw_dots(mi, sp->inc); + sp->inc++; + + if (sp->inc > sp->nlength - 1) { + sp->inc -= sp->nlength; + sp->erase = 1; + } + if (sp->redrawing) { + for (i = 0; i < REDRAWSTEP; i++) { + j = (sp->inc - sp->redrawpos + sp->nlength) % sp->nlength; + draw_dots(mi, j); + + if (++(sp->redrawpos) >= sp->nlength) { + sp->redrawing = 0; + break; + } + } + } +} + +ENTRYPOINT void +free_spiral(ModeInfo * mi) +{ + spiralstruct *sp; + + if (spirals == NULL) + return; + sp = &spirals[MI_SCREEN(mi)]; + + if (sp->traildots) + (void) free((void *) sp->traildots); +} + +#ifndef STANDALONE +ENTRYPOINT void +refresh_spiral(ModeInfo * mi) +{ + spiralstruct *sp; + + if (spirals == NULL) + return; + sp = &spirals[MI_SCREEN(mi)]; + + MI_CLEARWINDOW(mi); + sp->redrawing = 1; + sp->redrawpos = 0; +} +#endif + +XSCREENSAVER_MODULE ("Spiral", spiral) + +#endif /* MODE_spiral */ |