diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 11:09:41 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 11:09:41 +0000 |
commit | 95c2d1cbda23a41cdf6e63520c7f0b825e63dd5b (patch) | |
tree | 06d3ffa4312e568c4157f69fe1bddaddec9bc497 /app/xlockmore/modes/munch.c | |
parent | 3928433848e2d6a9356f3d438a14b32a4f87f660 (diff) |
Importing xlockmore 5.22
Diffstat (limited to 'app/xlockmore/modes/munch.c')
-rw-r--r-- | app/xlockmore/modes/munch.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/app/xlockmore/modes/munch.c b/app/xlockmore/modes/munch.c new file mode 100644 index 000000000..687deac65 --- /dev/null +++ b/app/xlockmore/modes/munch.c @@ -0,0 +1,268 @@ +/* -*- Mode: C; tab-width: 4 -*- */ +/* munch --- munching squares */ + +#if !defined( lint ) && !defined( SABER ) +static const char sccsid[] = "@(#)munch.c 5.00 2000/11/01 xlockmore"; + +#endif + +/*- + * 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. + * + * Tim Showalter <tjs@andrew.cmu.edu> + * + * Copyright 1997, Tim Showalter + * Permission is granted to copy, modify, and use this as long + * as this notice remains intact. No warranties are expressed or implied. + * CMU Sucks. + * + * Some code stolen from / This is meant to work with + * xscreensaver, Copyright (c) 1992, 1995, 1996 + * Jamie Zawinski <jwz@jwz.org> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * Revision History: + * 01-Nov-2000: Allocation checks + */ + +/*- + * Munching Squares is this simplistic, silly screen hack (according to + * HAKMEM, discovered by Jackson Wright in 1962) where you take Y = X XOR T + * and graph it over and over. According to HAKMEM, it takes 5 instructions + * of PDP-1 assembly. This is a little more complicated than that, mostly X's + * fault, but it does some other random things. + * http://www.inwap.com/pdp10/hbaker/hakmem/hacks.html#item146 + */ + +#ifdef STANDALONE +#define MODE_munch +#define PROGCLASS "Munch" +#define HACK_INIT init_munch +#define HACK_DRAW draw_munch +#define munch_opts xlockmore_opts +#define DEFAULTS "*delay: 5000 \n" \ + "*cycles: 7 \n" +#include "xlockmore.h" /* from the xscreensaver distribution */ +#else /* !STANDALONE */ +#include "xlock.h" /* from the xlockmore distribution */ +#endif /* !STANDALONE */ + +#ifdef MODE_munch + +ModeSpecOpt munch_opts = +{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; + +#ifdef USE_MODULES +ModStruct munch_description = +{"munch", "init_munch", "draw_munch", "release_munch", + "init_munch", "init_munch", (char *) NULL, &munch_opts, + 5000, 1, 7, 1, 64, 1.0, "", + "Shows munching squares", 0, NULL}; + +#endif + +#ifdef DEBUG +#include <assert.h> +#endif + +/* flags for random things. Must be < log2(random's maximum), incidentially. */ +#define SHIFT_KX (0x01) +#define SHIFT_KT (0x02) +#define SHIFT_KY (0x04) +#define GRAV (0x08) + +typedef struct { + int width, height; + int logminwidth; + int logmaxwidth; + GC gc; + int thiswidth; + int t; + int atX, atY; + int kX, kT, kY; + int grav; +} munchstruct; + +static munchstruct *munches = (munchstruct *) NULL; + +static void +munchBit(ModeInfo * mi, int width, /* pixels */ + int atX, int atY, /* pixels */ + int kX, int kT, int kY, /* pixels */ + int grav /* 0 or not */ ) +{ + munchstruct *mp = &munches[MI_SCREEN(mi)]; + + int x, y; + int drawX, drawY; + +#if 0 + (void) fprintf(stderr, "Doing width %d at %d %d shift %d %d %d grav %d\n", + width, atX, atY, kX, kT, kY, grav); +#endif + + for (x = 0; x < width; x++) { + /* figure out the next point */ + y = ((x ^ ((mp->t + kT) % width)) + kY) % width; + + drawX = ((x + kX) % width) + atX; + drawY = (grav ? y + atY : atY + width - 1 - y); + + /* used to be bugs where it would draw partially offscreen. + while that might be a pretty feature, I didn't want it to do + that yet. if these trigger, please let me know. + */ +#ifdef DEBUG + assert(drawX >= 0 && drawX < MI_WIDTH(mi)); + assert(drawY >= 0 && drawY < MI_HEIGHT(mi)); +#endif + + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), mp->gc, drawX, drawY); + /* XXX may want to change this to XDrawPoints, + but it's fast enough without it for the moment. */ + + } +} + +/* + * dumb way to get # of digits in number. Probably faster than actually + * doing a log and a division, maybe. + */ +static int +dumb_log_2(int k) +{ + int r = -1; + + while (k > 0) { + k >>= 1; + r++; + } + return r; +} + +void +init_munch(ModeInfo * mi) +{ + Display *display = MI_DISPLAY(mi); + munchstruct *mp; + + if (munches == NULL) { + if ((munches = (munchstruct *) calloc(MI_NUM_SCREENS(mi), + sizeof (munchstruct))) == NULL) + return; + } + mp = &munches[MI_SCREEN(mi)]; + + if (mp->gc == None) { + if ((mp->gc = XCreateGC(display, MI_WINDOW(mi), + (unsigned long) 0, (XGCValues *) NULL)) == None) + return; + } + mp->width = MI_WIDTH(mi); + mp->height = MI_HEIGHT(mi); + + /* We need a square; limit on screen size? */ + /* we want a power of 2 for the width or the munch doesn't fill up. */ + mp->logmaxwidth = (int) + dumb_log_2((mp->height < mp->width) ? mp->height : mp->width); + + XSetFunction(display, mp->gc, GXxor); + + mp->logminwidth = MI_CYCLES(mi); + if (mp->logminwidth < 2 || MI_IS_ICONIC(mi)) + mp->logminwidth = 2; + + if (mp->logmaxwidth < mp->logminwidth) + mp->logmaxwidth = mp->logminwidth; + + mp->t = 0; + + MI_CLEARWINDOW(mi); +} + +void +draw_munch(ModeInfo * mi) +{ + munchstruct *mp; + + if (munches == NULL) + return; + mp = &munches[MI_SCREEN(mi)]; + if (mp->gc == None) + return; + + MI_IS_DRAWN(mi) = True; + if (!mp->t) { /* New one */ + int randflags = (int) LRAND(); + + /* choose size -- power of two */ + mp->thiswidth = (int) (1 << (mp->logminwidth + + (LRAND() % (1 + mp->logmaxwidth - mp->logminwidth)))); + + if (MI_NPIXELS(mi) > 2) + XSetForeground(MI_DISPLAY(mi), mp->gc, + MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)))); + else /* Xor'red so WHITE may not be appropriate */ + XSetForeground(MI_DISPLAY(mi), mp->gc, 1); + + mp->atX = (int) (LRAND() % + ((mp->width <= mp->thiswidth) ? 1 : mp->width - mp->thiswidth)); + mp->atY = (int) (LRAND() % + ((mp->height <= mp->thiswidth) ? 1 : mp->height - mp->thiswidth)); + + /* wrap-around by these values; no need to % + as we end up doing that later anyway */ + mp->kX = (int) ((randflags & SHIFT_KX) ? LRAND() % mp->thiswidth : 0); + mp->kT = (int) ((randflags & SHIFT_KT) ? LRAND() % mp->thiswidth : 0); + mp->kY = (int) ((randflags & SHIFT_KY) ? LRAND() % mp->thiswidth : 0); + + /* set the gravity of the munch, or rather, + which direction we draw stuff in. */ + mp->grav = randflags & GRAV; + } + /* Finally draw this munching square. */ + munchBit(mi, + mp->thiswidth, /* Width, in pixels */ + /* draw at this location */ + mp->atX, mp->atY, mp->kX, mp->kT, mp->kY, mp->grav); + + mp->t++; + if (mp->t == mp->thiswidth) + mp->t = 0; +} + +void +release_munch(ModeInfo * mi) +{ + if (munches != NULL) { + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { + munchstruct *mp = &munches[screen]; + + if (mp->gc != None) + XFreeGC(MI_DISPLAY(mi), mp->gc); + } + free(munches); + munches = (munchstruct *) NULL; + } +} + +#endif /* MODE_munch */ |