diff options
author | Simon Rettberg | 2018-10-16 10:08:48 +0200 |
---|---|---|
committer | Simon Rettberg | 2018-10-16 10:08:48 +0200 |
commit | d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 (patch) | |
tree | cbddf8e50f35a9c6e878a5bfe3c6d625d99e12ba /hacks/rotor.c | |
download | xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.gz xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.xz xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.zip |
Original 5.40
Diffstat (limited to 'hacks/rotor.c')
-rw-r--r-- | hacks/rotor.c | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/hacks/rotor.c b/hacks/rotor.c new file mode 100644 index 0000000..c22479b --- /dev/null +++ b/hacks/rotor.c @@ -0,0 +1,389 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* rotor --- a swirly rotor */ + +#if 0 +static const char sccsid[] = "@(#)rotor.c 5.00 2000/11/01 xlockmore"; +#endif + +/*- + * Copyright (c) 1991 by Patrick J. Naughton. + * + * 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: Compatible with xscreensaver + * 08-Mar-1995: CAT stuff for ## was tripping up some C compilers. Removed. + * 01-Dec-1993: added patch for AIXV3 from Tom McConnell + * <tmcconne@sedona.intel.com> + * 11-Nov-1990: put into xlock by Steve Zellers <zellers@sun.com> + * 16-Oct-1990: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' + * simulator) + */ + +#ifdef STANDALONE +#define MODE_rotor +#define DEFAULTS "*delay: 10000 \n" \ + "*count: 4 \n" \ + "*cycles: 20 \n" \ + "*size: -6 \n" \ + "*ncolors: 200 \n" \ + "*fpsSolid: true \n" \ + "*lowrez: True \n" \ + +# define SMOOTH_COLORS +# define release_rotor 0 +# define reshape_rotor 0 +# define rotor_handle_event 0 +# include "xlockmore.h" /* in xscreensaver distribution */ +#else /* STANDALONE */ +# include "xlock.h" /* in xlockmore distribution */ +#endif /* STANDALONE */ + +#ifdef MODE_rotor + +ENTRYPOINT ModeSpecOpt rotor_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct rotor_description = +{"rotor", "init_rotor", "draw_rotor", (char *) NULL, + "refresh_rotor", "init_rotor", "free_rotor", &rotor_opts, + 100, 4, 100, -6, 64, 0.3, "", + "Shows Tom's Roto-Rooter", 0, NULL}; + +#endif + +/*- + * A 'batchcount' of 3 or 4 works best! + */ + +#define MAXANGLE 3000.0 /* irrectangular (was 10000.0) */ + +/* How many segments to draw per cycle when redrawing */ +#define REDRAWSTEP 3 + +typedef struct { + float angle; + float radius; + float start_radius; + float end_radius; + float radius_drift_max; + float radius_drift_now; + + float ratio; + float start_ratio; + float end_ratio; + float ratio_drift_max; + float ratio_drift_now; +} elem; + +typedef struct { + int pix; + int lastx, lasty; + int num, rotor, prev; + int nsave; + float angle; + int centerx, centery; + int prevcenterx, prevcentery; + unsigned char firsttime; + unsigned char iconifiedscreen; /* for iconified view */ + unsigned char forward; + unsigned char unused; + elem *elements; + XPoint *save; + int redrawing, redrawpos; + int linewidth; +} rotorstruct; + +static rotorstruct *rotors = (rotorstruct *) NULL; + +ENTRYPOINT void +free_rotor(ModeInfo * mi) +{ + rotorstruct *rp = &rotors[MI_SCREEN(mi)]; + if (rp->elements != NULL) { + (void) free((void *) rp->elements); + rp->elements = (elem *) NULL; + } + if (rp->save != NULL) { + (void) free((void *) rp->save); + rp->save = (XPoint *) NULL; + } +} + +ENTRYPOINT void +init_rotor (ModeInfo * mi) +{ + int x; + elem *pelem; + unsigned char wasiconified; + rotorstruct *rp; + + MI_INIT (mi, rotors); + rp = &rotors[MI_SCREEN(mi)]; + +#ifdef HAVE_JWXYZ + jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False); +#endif + + rp->prevcenterx = rp->centerx; + rp->prevcentery = rp->centery; + + rp->centerx = MI_WIDTH(mi) / 2; + rp->centery = MI_HEIGHT(mi) / 2; + + rp->redrawing = 0; + /* + * sometimes, you go into iconified view, only to see a really whizzy pattern + * that you would like to look more closely at. Normally, clicking in the + * icon reinitializes everything - but I don't, cuz I'm that kind of guy. + * HENCE, the wasiconified stuff you see here. + */ + + wasiconified = rp->iconifiedscreen; + rp->iconifiedscreen = MI_IS_ICONIC(mi); + + if (wasiconified && !rp->iconifiedscreen) + rp->firsttime = True; + else { + + /* This is a fudge is needed since prevcenter may not be set when it comes + from the the random mode and return is pressed (and its not the first + mode that was running). This assumes that the size of the lock screen + window / size of the icon window = 12 */ + if (!rp->prevcenterx) + rp->prevcenterx = rp->centerx * 12; + if (!rp->prevcentery) + rp->prevcentery = rp->centery * 12; + + rp->num = MI_COUNT(mi); + if (rp->num < 0) { + rp->num = NRAND(-rp->num) + 1; + if (rp->elements != NULL) { + (void) free((void *) rp->elements); + rp->elements = (elem *) NULL; + } + } + if (rp->elements == NULL) + if ((rp->elements = (elem *) calloc(rp->num, + sizeof (elem))) == NULL) { + free_rotor(mi); + return; + } + rp->nsave = MI_CYCLES(mi); + if (rp->nsave <= 1) + rp->nsave = 2; + if (rp->save == NULL) + if ((rp->save = (XPoint *) malloc(rp->nsave * + sizeof (XPoint))) == NULL) { + free_rotor(mi); + return; + } + for (x = 0; x < rp->nsave; x++) { + rp->save[x].x = rp->centerx; + rp->save[x].y = rp->centery; + } + + pelem = rp->elements; + + for (x = rp->num; --x >= 0; pelem++) { + pelem->radius_drift_max = 1.0; + pelem->radius_drift_now = 1.0; + + pelem->end_radius = 100.0; + + pelem->ratio_drift_max = 1.0; + pelem->ratio_drift_now = 1.0; + pelem->end_ratio = 10.0; + } + if (MI_NPIXELS(mi) > 2) + rp->pix = NRAND(MI_NPIXELS(mi)); + + rp->rotor = 0; + rp->prev = 1; + rp->lastx = rp->centerx; + rp->lasty = rp->centery; + rp->angle = (float) NRAND((long) MAXANGLE) / 3.0; + rp->forward = rp->firsttime = True; + } + rp->linewidth = MI_SIZE(mi); + + if (rp->linewidth == 0) + rp->linewidth = 1; + if (rp->linewidth < 0) + rp->linewidth = NRAND(-rp->linewidth) + 1; + + MI_CLEARWINDOW(mi); +} + +ENTRYPOINT void +draw_rotor (ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + GC gc = MI_GC(mi); + register elem *pelem; + int thisx, thisy; + int i; + int x_1, y_1, x_2, y_2; + rotorstruct *rp; + + if (rotors == NULL) + return; + rp = &rotors[MI_SCREEN(mi)]; + if (rp->elements == NULL) + return; + + MI_IS_DRAWN(mi) = True; + if (!rp->iconifiedscreen) { + thisx = rp->centerx; + thisy = rp->centery; + } else { + thisx = rp->prevcenterx; + thisy = rp->prevcentery; + } + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), rp->linewidth, + LineSolid, CapButt, JoinMiter); + for (i = rp->num, pelem = rp->elements; --i >= 0; pelem++) { + if (pelem->radius_drift_max <= pelem->radius_drift_now) { + pelem->start_radius = pelem->end_radius; + pelem->end_radius = (float) NRAND(40000) / 100.0 - 200.0; + pelem->radius_drift_max = (float) NRAND(100000) + 10000.0; + pelem->radius_drift_now = 0.0; + } + if (pelem->ratio_drift_max <= pelem->ratio_drift_now) { + pelem->start_ratio = pelem->end_ratio; + pelem->end_ratio = (float) NRAND(2000) / 100.0 - 10.0; + pelem->ratio_drift_max = (float) NRAND(100000) + 10000.0; + pelem->ratio_drift_now = 0.0; + } + pelem->ratio = pelem->start_ratio + + (pelem->end_ratio - pelem->start_ratio) / + pelem->ratio_drift_max * pelem->ratio_drift_now; + pelem->angle = rp->angle * pelem->ratio; + pelem->radius = pelem->start_radius + + (pelem->end_radius - pelem->start_radius) / + pelem->radius_drift_max * pelem->radius_drift_now; + + thisx += (int) (COSF(pelem->angle) * pelem->radius); + thisy += (int) (SINF(pelem->angle) * pelem->radius); + + pelem->ratio_drift_now += 1.0; + pelem->radius_drift_now += 1.0; + } + if (rp->firsttime) + rp->firsttime = False; + else { + XSetForeground(display, gc, MI_BLACK_PIXEL(mi)); + + x_1 = (int) rp->save[rp->rotor].x; + y_1 = (int) rp->save[rp->rotor].y; + x_2 = (int) rp->save[rp->prev].x; + y_2 = (int) rp->save[rp->prev].y; + + if (rp->iconifiedscreen) { + x_1 = x_1 * rp->centerx / rp->prevcenterx; + x_2 = x_2 * rp->centerx / rp->prevcenterx; + y_1 = y_1 * rp->centery / rp->prevcentery; + y_2 = y_2 * rp->centery / rp->prevcentery; + } + XDrawLine(display, MI_WINDOW(mi), gc, x_1, y_1, x_2, y_2); + + if (MI_NPIXELS(mi) > 2) { + XSetForeground(display, gc, MI_PIXEL(mi, rp->pix)); + if (++rp->pix >= MI_NPIXELS(mi)) + rp->pix = 0; + } else + XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); + + x_1 = rp->lastx; + y_1 = rp->lasty; + x_2 = thisx; + y_2 = thisy; + + if (rp->iconifiedscreen) { + x_1 = x_1 * rp->centerx / rp->prevcenterx; + x_2 = x_2 * rp->centerx / rp->prevcenterx; + y_1 = y_1 * rp->centery / rp->prevcentery; + y_2 = y_2 * rp->centery / rp->prevcentery; + } + XDrawLine(display, MI_WINDOW(mi), gc, x_1, y_1, x_2, y_2); + } + rp->save[rp->rotor].x = rp->lastx = thisx; + rp->save[rp->rotor].y = rp->lasty = thisy; + + ++rp->rotor; + rp->rotor %= rp->nsave; + ++rp->prev; + rp->prev %= rp->nsave; + if (rp->forward) { + rp->angle += 0.01; + if (rp->angle >= MAXANGLE) { + rp->angle = MAXANGLE; + rp->forward = False; + } + } else { + rp->angle -= 0.1; + if (rp->angle <= 0) { + rp->angle = 0.0; + rp->forward = True; + } + } + if (rp->redrawing) { + int j; + + for (i = 0; i < REDRAWSTEP; i++) { + j = (rp->rotor - rp->redrawpos + rp->nsave) % rp->nsave; + + x_1 = (int) rp->save[j].x; + y_1 = (int) rp->save[j].y; + x_2 = (int) rp->save[(j - 1 + rp->nsave) % rp->nsave].x; + y_2 = (int) rp->save[(j - 1 + rp->nsave) % rp->nsave].y; + + if (rp->iconifiedscreen) { + x_1 = x_1 * rp->centerx / rp->prevcenterx; + x_2 = x_2 * rp->centerx / rp->prevcenterx; + y_1 = y_1 * rp->centery / rp->prevcentery; + y_2 = y_2 * rp->centery / rp->prevcentery; + } + XDrawLine(display, MI_WINDOW(mi), gc, x_1, y_1, x_2, y_2); + + if (++(rp->redrawpos) >= rp->nsave) { + rp->redrawing = 0; + break; + } + } + } + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, + LineSolid, CapButt, JoinMiter); +} + +#ifndef STANDALONE +ENTRYPOINT void +refresh_rotor (ModeInfo * mi) +{ + rotorstruct *rp; + + if (rotors == NULL) + return; + rp = &rotors[MI_SCREEN(mi)]; + + MI_CLEARWINDOW(mi); + rp->redrawing = 1; + rp->redrawpos = 1; +} +#endif + +XSCREENSAVER_MODULE ("Rotor", rotor) + +#endif /* MODE_rotor */ |