diff options
Diffstat (limited to 'hacks/thornbird.c')
-rw-r--r-- | hacks/thornbird.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/hacks/thornbird.c b/hacks/thornbird.c new file mode 100644 index 0000000..07e0cbd --- /dev/null +++ b/hacks/thornbird.c @@ -0,0 +1,264 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* thornbird --- continuously varying Thornbird set */ + +#if 0 +static const char sccsid[] = "@(#)thornbird.c 5.00 2000/11/01 xlockmore"; +#endif + +/*- + * Copyright (c) 1996 by Tim Auckland <tda10.geo@yahoo.com> + * + * 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. + * + * "thornbird" shows a view of the "Bird in a Thornbush" fractal, + * continuously varying the three free parameters. + * + * Revision History: + * 01-Nov-2000: Allocation checks + * 04-Jun-1999: 3D tumble added by Tim Auckland + * 31-Jul-1997: Adapted from discrete.c Copyright (c) 1996 by Tim Auckland + */ + +#ifdef STANDALONE +# define MODE_thornbird +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 100 \n" \ + "*cycles: 400 \n" \ + "*ncolors: 64 \n" \ + "*fpsSolid: true \n" \ + "*ignoreRotation: True \n" \ + "*lowrez: True \n" \ + +# define BRIGHT_COLORS +# define release_thornbird 0 +# define reshape_thornbird 0 +# define thornbird_handle_event 0 +# include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +# include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_thornbird + +ENTRYPOINT ModeSpecOpt thornbird_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct thornbird_description = +{"thornbird", "init_thornbird", "draw_thornbird", (char *) NULL, + "refresh_thornbird", "init_thornbird", "free_thornbird", þbird_opts, + 1000, 800, 16, 1, 64, 1.0, "", + "Shows an animated Bird in a Thorn Bush fractal map", 0, NULL}; + +#endif + +#define balance_rand(v) ((LRAND()/MAXRAND*(v))-((v)/2)) /* random around 0 */ + +typedef struct { + int maxx; + int maxy; /* max of the screen */ + double a; + double b; + double c; + double d; + double e; + double i; + double j; /* thornbird parameters */ + struct { + double f1; + double f2; + } liss; + struct { + double theta; + double dtheta; + double phi; + double dphi; + } tumble; + int inc; + int pix; + int count; + int nbuffers; + XPoint **pointBuffer; /* pointer for XDrawPoints */ +} thornbirdstruct; + +static thornbirdstruct *thornbirds = (thornbirdstruct *) NULL; + +ENTRYPOINT void +free_thornbird(ModeInfo * mi) +{ + thornbirdstruct *hp = þbirds[MI_SCREEN(mi)]; + if (hp->pointBuffer != NULL) { + int buffer; + + for (buffer = 0; buffer < hp->nbuffers; buffer++) + if (hp->pointBuffer[buffer] != NULL) + (void) free((void *) hp->pointBuffer[buffer]); + (void) free((void *) hp->pointBuffer); + hp->pointBuffer = (XPoint **) NULL; + } +} + +ENTRYPOINT void +init_thornbird (ModeInfo * mi) +{ + thornbirdstruct *hp; + + MI_INIT (mi, thornbirds); + hp = þbirds[MI_SCREEN(mi)]; + + + hp->maxx = MI_WIDTH(mi); + hp->maxy = MI_HEIGHT(mi); + + hp->b = 0.1; + hp->i = hp->j = 0.1; + + hp->pix = 0; + hp->inc = 0; + + hp->nbuffers = MI_CYCLES(mi); + + if (hp->pointBuffer == NULL) + if ((hp->pointBuffer = (XPoint **) calloc(MI_CYCLES(mi), + sizeof (XPoint *))) == NULL) { + free_thornbird(mi); + return; + } + + if (hp->pointBuffer[0] == NULL) + if ((hp->pointBuffer[0] = (XPoint *) malloc(MI_COUNT(mi) * + sizeof (XPoint))) == NULL) { + free_thornbird(mi); + return; + } + + /* select frequencies for parameter variation */ + hp->liss.f1 = LRAND() % 5000; + hp->liss.f2 = LRAND() % 2000; + + /* choose random 3D tumbling */ + hp->tumble.theta = 0; + hp->tumble.phi = 0; + hp->tumble.dtheta = balance_rand(0.001); + hp->tumble.dphi = balance_rand(0.005); + + /* Clear the background. */ + MI_CLEARWINDOW(mi); + + hp->count = 0; +} + + +ENTRYPOINT void +draw_thornbird(ModeInfo * mi) +{ + Display *dsp = MI_DISPLAY(mi); + Window win = MI_WINDOW(mi); + double oldj, oldi; + int batchcount = MI_COUNT(mi); + int k; + XPoint *xp; + GC gc = MI_GC(mi); + int erase; + int current; + + double sint, cost, sinp, cosp; + thornbirdstruct *hp; + + if (thornbirds == NULL) + return; + hp = þbirds[MI_SCREEN(mi)]; + if (hp->pointBuffer == NULL) + return; + + erase = (hp->inc + 1) % MI_CYCLES(mi); + current = hp->inc % MI_CYCLES(mi); + k = batchcount; + + + xp = hp->pointBuffer[current]; + + /* vary papameters */ + hp->a = 1.99 + (0.4 * sin(hp->inc / hp->liss.f1) + + 0.05 * cos(hp->inc / hp->liss.f2)); + hp->c = 0.80 + (0.15 * cos(hp->inc / hp->liss.f1) + + 0.05 * sin(hp->inc / hp->liss.f2)); + + /* vary view */ + hp->tumble.theta += hp->tumble.dtheta; + hp->tumble.phi += hp->tumble.dphi; + sint = sin(hp->tumble.theta); + cost = cos(hp->tumble.theta); + sinp = sin(hp->tumble.phi); + cosp = cos(hp->tumble.phi); + + while (k--) { + oldj = hp->j; + oldi = hp->i; + + hp->j = oldi; + hp->i = (1 - hp->c) * cos(M_PI * hp->a * oldj) + hp->c * hp->b; + hp->b = oldj; + + xp->x = (short) + (hp->maxx / 2 * (1 + + sint*hp->j + cost*cosp*hp->i - cost*sinp*hp->b)); + xp->y = (short) + (hp->maxy / 2 * (1 + - cost*hp->j + sint*cosp*hp->i - sint*sinp*hp->b)); + xp++; + } + + MI_IS_DRAWN(mi) = True; + + if (MI_COUNT(mi) < 1) MI_COUNT(mi) = 1; + if (hp->pointBuffer[erase] == NULL) { + if ((hp->pointBuffer[erase] = (XPoint *) malloc(MI_COUNT(mi) * + sizeof (XPoint))) == NULL) { + free_thornbird(mi); + return; + } + } else { + XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi)); + XDrawPoints(dsp, win, gc, hp->pointBuffer[erase], + batchcount, CoordModeOrigin); + } + if (MI_NPIXELS(mi) > 2) { + XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); +#if 0 + if (erase == 0) /* change colours after "cycles" cycles */ +#else + if (!((hp->inc + 1) % (1 + (MI_CYCLES(mi) / 3)))) /* jwz: sooner */ +#endif + if (++hp->pix >= MI_NPIXELS(mi)) + hp->pix = 0; + } else + XSetForeground(dsp, gc, MI_WHITE_PIXEL(mi)); + + XDrawPoints(dsp, win, gc, hp->pointBuffer[current], + batchcount, CoordModeOrigin); + hp->inc++; +} + +#ifndef STANDALONE +ENTRYPOINT void +refresh_thornbird (ModeInfo * mi) +{ + MI_CLEARWINDOW(mi); +} +#endif + + +XSCREENSAVER_MODULE ("Thornbird", thornbird) + +#endif /* MODE_thornbird */ |