summaryrefslogtreecommitdiffstats
path: root/hacks/lissie.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/lissie.c')
-rw-r--r--hacks/lissie.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/hacks/lissie.c b/hacks/lissie.c
new file mode 100644
index 0000000..bb631b2
--- /dev/null
+++ b/hacks/lissie.c
@@ -0,0 +1,322 @@
+/* -*- Mode: C; tab-width: 4 -*- */
+/* lissie --- the Lissajous worm */
+
+#if 0
+static const char sccsid[] = "@(#)lissie.c 5.00 2000/11/01 xlockmore";
+#endif
+
+/*-
+ * lissie.c - The Lissajous worm for xlock, the X Window System
+ * lockscreen.
+ *
+ * Copyright (c) 1996 by Alexander Jolk <ub9x@rz.uni-karlsruhe.de>
+ *
+ * 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
+ * 18-Aug-1996: added refresh-hook.
+ * 01-May-1996: written.
+ */
+
+#ifdef STANDALONE
+# define MODE_lissie
+# define DEFAULTS "*delay: 10000 \n" \
+ "*count: 1 \n" \
+ "*cycles: 20000 \n" \
+ "*size: -200 \n" \
+ "*ncolors: 200 \n" \
+ "*fpsSolid: true \n" \
+
+# define SMOOTH_COLORS
+# define release_lissie 0
+# define reshape_lissie 0
+# define lissie_handle_event 0
+# include "xlockmore.h" /* in xscreensaver distribution */
+#else /* STANDALONE */
+# include "xlock.h" /* in xlockmore distribution */
+#endif /* STANDALONE */
+
+#ifdef MODE_lissie
+
+ENTRYPOINT ModeSpecOpt lissie_opts =
+{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
+
+#ifdef USE_MODULES
+ModStruct lissie_description =
+{"lissie", "init_lissie", "draw_lissie", (char *) NULL,
+ "refresh_lissie", "init_lissie", "free_lissie", &lissie_opts,
+ 10000, 1, 2000, -200, 64, 0.6, "",
+ "Shows lissajous worms", 0, NULL};
+
+#endif
+
+#define MINSIZE 1
+
+#define Lissie(n)\
+ if (lissie->loc[(n)].x > 0 && lissie->loc[(n)].y > 0 &&\
+ lissie->loc[(n)].x <= lp->width && lissie->loc[(n)].y <= lp->height) {\
+ if (lissie->ri < 2)\
+ XDrawPoint(display, MI_WINDOW(mi),\
+ gc, lissie->loc[(n)].x, lissie->loc[(n)].y);\
+ else\
+ XDrawArc(display, MI_WINDOW(mi), gc,\
+ lissie->loc[(n)].x - lissie->ri / 2,\
+ lissie->loc[(n)].y - lissie->ri / 2,\
+ lissie->ri, lissie->ri, 0, 23040);\
+ }
+
+#define FLOATRAND(min,max) ((min)+(LRAND()/MAXRAND)*((max)-(min)))
+#define INTRAND(min,max) ((min)+NRAND((max)-(min)+1))
+
+#define MINDT 0.01
+#define MAXDT 0.15
+
+#define MAXLISSIELEN 100
+#define MINLISSIELEN 10
+#define MINLISSIES 1
+
+/* How many segments to draw per cycle when redrawing */
+#define REDRAWSTEP 3
+
+typedef struct {
+ double tx, ty, dtx, dty;
+ int xi, yi, ri, rx, ry, len, pos;
+ int redrawing, redrawpos;
+ XPoint loc[MAXLISSIELEN];
+ unsigned long color;
+} lissiestruct;
+
+typedef struct {
+ Bool painted;
+ int width, height;
+ int nlissies;
+ lissiestruct *lissie;
+ int loopcount;
+} lissstruct;
+
+static lissstruct *lisses = (lissstruct *) NULL;
+
+
+static void
+drawlissie(ModeInfo * mi, lissiestruct * lissie)
+{
+ Display *display = MI_DISPLAY(mi);
+ GC gc = MI_GC(mi);
+ lissstruct *lp = &lisses[MI_SCREEN(mi)];
+ int p = (++lissie->pos) % MAXLISSIELEN;
+ int oldp = (lissie->pos - lissie->len + MAXLISSIELEN) % MAXLISSIELEN;
+
+ /* Let time go by ... */
+ lissie->tx += lissie->dtx;
+ lissie->ty += lissie->dty;
+ if (lissie->tx > 2 * M_PI)
+ lissie->tx -= 2 * M_PI;
+ if (lissie->ty > 2 * M_PI)
+ lissie->ty -= 2 * M_PI;
+
+ /* vary both (x/y) speeds by max. 1% */
+ lissie->dtx *= FLOATRAND(0.99, 1.01);
+ lissie->dty *= FLOATRAND(0.99, 1.01);
+ if (lissie->dtx < MINDT)
+ lissie->dtx = MINDT;
+ else if (lissie->dtx > MAXDT)
+ lissie->dtx = MAXDT;
+ if (lissie->dty < MINDT)
+ lissie->dty = MINDT;
+ else if (lissie->dty > MAXDT)
+ lissie->dty = MAXDT;
+
+ lissie->loc[p].x = lissie->xi + (int) (sin(lissie->tx) * lissie->rx);
+ lissie->loc[p].y = lissie->yi + (int) (sin(lissie->ty) * lissie->ry);
+
+ /* Mask */
+ XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
+ Lissie(oldp);
+
+ /* Redraw */
+ if (MI_NPIXELS(mi) > 2) {
+ XSetForeground(display, gc, MI_PIXEL(mi, lissie->color));
+ if (++lissie->color >= (unsigned) MI_NPIXELS(mi))
+ lissie->color = 0;
+ } else
+ XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
+ Lissie(p);
+ if (lissie->redrawing) {
+ int i;
+
+ lissie->redrawpos++;
+ /* This compensates for the changed p
+ since the last callback. */
+
+ for (i = 0; i < REDRAWSTEP; i++) {
+ Lissie((p - lissie->redrawpos + MAXLISSIELEN) % MAXLISSIELEN);
+ if (++(lissie->redrawpos) >= lissie->len) {
+ lissie->redrawing = 0;
+ break;
+ }
+ }
+ }
+}
+
+static void
+initlissie(ModeInfo * mi, lissiestruct * lissie)
+{
+ lissstruct *lp = &lisses[MI_SCREEN(mi)];
+ int size = MI_SIZE(mi);
+ int i;
+
+ if (MI_NPIXELS(mi) > 2)
+ lissie->color = NRAND(MI_NPIXELS(mi));
+ else
+ lissie->color = MI_WHITE_PIXEL(mi);
+ /* Initialize parameters */
+ if (size < -MINSIZE)
+ lissie->ri = NRAND(MIN(-size, MAX(MINSIZE,
+ MIN(lp->width, lp->height) / 4)) - MINSIZE + 1) + MINSIZE;
+ else if (size < MINSIZE) {
+ if (!size)
+ lissie->ri = MAX(MINSIZE, MIN(lp->width, lp->height) / 4);
+ else
+ lissie->ri = MINSIZE;
+ } else
+ lissie->ri = MIN(size, MAX(MINSIZE, MIN(lp->width, lp->height) / 4));
+ lissie->xi = INTRAND(lp->width / 4 + lissie->ri,
+ lp->width * 3 / 4 - lissie->ri);
+ lissie->yi = INTRAND(lp->height / 4 + lissie->ri,
+ lp->height * 3 / 4 - lissie->ri);
+ lissie->rx = INTRAND(lp->width / 4,
+ MIN(lp->width - lissie->xi, lissie->xi)) - 2 * lissie->ri;
+ lissie->ry = INTRAND(lp->height / 4,
+ MIN(lp->height - lissie->yi, lissie->yi)) - 2 * lissie->ri;
+ lissie->len = INTRAND(MINLISSIELEN, MAXLISSIELEN - 1);
+ lissie->pos = 0;
+
+ lissie->redrawing = 0;
+
+ lissie->tx = FLOATRAND(0, 2 * M_PI);
+ lissie->ty = FLOATRAND(0, 2 * M_PI);
+ lissie->dtx = FLOATRAND(MINDT, MAXDT);
+ lissie->dty = FLOATRAND(MINDT, MAXDT);
+
+ for (i = 0; i < MAXLISSIELEN; i++)
+ lissie->loc[i].x = lissie->loc[i].y = 0;
+}
+
+ENTRYPOINT void
+init_lissie (ModeInfo * mi)
+{
+ lissstruct *lp;
+ unsigned char ball;
+
+ MI_INIT (mi, lisses);
+ lp = &lisses[MI_SCREEN(mi)];
+
+ lp->width = MI_WIDTH(mi);
+
+#ifdef HAVE_JWXYZ
+ jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False);
+#endif
+
+ lp->height = MI_HEIGHT(mi);
+
+ lp->nlissies = MI_COUNT(mi);
+ if (lp->nlissies < -MINLISSIES) {
+ if (lp->lissie) {
+ (void) free((void *) lp->lissie);
+ lp->lissie = (lissiestruct *) NULL;
+ }
+ lp->nlissies = NRAND(-lp->nlissies - MINLISSIES + 1) + MINLISSIES;
+ } else if (lp->nlissies < MINLISSIES)
+ lp->nlissies = MINLISSIES;
+
+ lp->loopcount = 0;
+
+ if (lp->lissie == NULL)
+ if ((lp->lissie = (lissiestruct *) calloc(lp->nlissies,
+ sizeof (lissiestruct))) == NULL)
+ return;
+
+ MI_CLEARWINDOW(mi);
+ lp->painted = False;
+
+ for (ball = 0; ball < (unsigned char) lp->nlissies; ball++)
+ initlissie(mi, &lp->lissie[ball]);
+
+}
+
+ENTRYPOINT void
+draw_lissie (ModeInfo * mi)
+{
+ register unsigned char ball;
+ lissstruct *lp;
+
+ if (lisses == NULL)
+ return;
+ lp = &lisses[MI_SCREEN(mi)];
+ if (lp->lissie == NULL)
+ return;
+
+ MI_IS_DRAWN(mi) = True;
+
+ if (++lp->loopcount > MI_CYCLES(mi)) {
+ init_lissie(mi);
+ } else {
+ lp->painted = True;
+ for (ball = 0; ball < (unsigned char) lp->nlissies; ball++)
+ drawlissie(mi, &lp->lissie[ball]);
+ }
+}
+
+ENTRYPOINT void
+free_lissie (ModeInfo * mi)
+{
+ lissstruct *lp;
+
+ if (lisses == NULL)
+ return;
+ lp = &lisses[MI_SCREEN(mi)];
+
+ if (lp->lissie != NULL) {
+ (void) free((void *) lp->lissie);
+ /* lp->lissie = NULL; */
+ }
+}
+
+#ifndef STANDALONE
+ENTRYPOINT void
+refresh_lissie(ModeInfo * mi)
+{
+ int i;
+ lissstruct *lp;
+
+ if (lisses == NULL)
+ return;
+ lp = &lisses[MI_SCREEN(mi)];
+ if (lp->lissie == NULL)
+ return;
+
+ if (lp->painted) {
+ MI_CLEARWINDOW(mi);
+ for (i = 0; i < lp->nlissies; i++) {
+ lp->lissie[i].redrawing = 1;
+ lp->lissie[i].redrawpos = 0;
+ }
+ }
+}
+#endif
+
+XSCREENSAVER_MODULE ("Lissie", lissie)
+
+#endif /* MODE_lissie */