-/* xscreensaver, Copyright (c) 1992, 1995, 1997
- * Jamie Zawinski <jwz@netscape.com>
+/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 1999, 2003
+ * Jamie Zawinski <jwz@jwz.org>
*
* reaction/diffusion textures
* Copyright (c) 1997 Scott Draves spot@transmeta.com
#include <math.h>
#include "screenhack.h"
+#include <X11/Xutil.h>
-/* why doesn't this work??? */
#ifdef HAVE_XSHM_EXTENSION
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/extensions/XShm.h>
+# include "xshm.h"
+#endif /* HAVE_XSHM_EXTENSION */
+
+/* costs ~6% speed */
+#define dither_when_mapped 1
+
+static int verbose;
+static int ncolors = 0;
+static XColor *colors = 0;
+static Display *display;
+static Visual *visual;
+#if dither_when_mapped
+static unsigned char *mc = 0;
#endif
+static Colormap cmap = 0;
+static Window window;
+static int mapped;
+static int pdepth;
+static void random_colors(void);
+
+/* -----------------------------------------------------------
+ pixel hack, 8-bit pixel grid, first/next frame interface
+
+ pixack_init(int *size_h, int *size_v)
+ pixack_frame(char *pix_buf)
+ */
+
+
+#define bps 16
+#define mx ((1<<16)-1)
+
+/* you can replace integer mults wish shift/adds with these,
+ but it doesn't help on my 586 */
+#define x5(n) ((n<<2)+n)
+#define x7(n) ((n<<3)-n)
+
+/* why strip bit? */
+#define R (ya_random()&((1<<30)-1))
+
+static int frame = 0, epoch_time;
+static ushort *r1, *r2, *r1b, *r2b;
+static int width, height, npix;
+static int radius;
+static int reaction = 0;
+static int diffusion = 0;
+
+/* returns number of pixels that the pixack produces. called once. */
+static void
+pixack_init(int *size_h, int *size_v)
+{
+ int sz_base;
+ width = get_integer_resource ("width", "Integer");
+ height = get_integer_resource ("height", "Integer");
+ sz_base = 80 + (R%40);
+ if (width <= 0) width = (R%20) ? sz_base : (28 + R%10);
+ if (height <= 0) height = (R%20) ? sz_base : (28 + R%10);
+
+ /* jwz: when (and only when) XSHM is in use on an SGI 8-bit visual,
+ we get shear unless width is a multiple of 4. I don't understand
+ why. This is undoubtedly the wrong fix... */
+ width &= ~0x7;
+
+ /* don't go there */
+ if (width < 10) width = 10;
+ if (height < 10) height = 10;
+ epoch_time = get_integer_resource ("epoch", "Integer");
+ npix = (width + 2) * (height + 2);
+ r1 = (ushort *) malloc(sizeof(ushort) * npix);
+ r2 = (ushort *) malloc(sizeof(ushort) * npix);
+ r1b = (ushort *) malloc(sizeof(ushort) * npix);
+ r2b = (ushort *) malloc(sizeof(ushort) * npix);
+
+ if (!r1 || !r2 || !r1b || !r2b) {
+ fprintf(stderr, "not enough memory for %d pixels.\n", npix);
+ exit(1);
+ }
+
+ *size_h = width;
+ *size_v = height;
+}
#define test_pattern_hyper 0
-/* costs ~6% speed */
-#define dither_when_mapped 1
+
+/* returns the pixels. called many times. */
+static void
+pixack_frame(char *pix_buf)
+{
+ int i, j;
+ int w2 = width + 2;
+ ushort *t;
+#if test_pattern_hyper
+ if (frame&0x100)
+ sleep(1);
+#endif
+ if (verbose) {
+ double tm = 0;
+ struct timeval tp;
+ if (!(frame%100)) {
+ double tm2;
+#ifdef GETTIMEOFDAY_TWO_ARGS
+ struct timezone tzp;
+ gettimeofday(&tp, &tzp);
+#else
+ gettimeofday(&tp);
+#endif
+ tm2 = tp.tv_sec + tp.tv_usec * 1e-6;
+ if (frame > 0)
+ printf("fps = %2.4g\n", 100.0 / (tm2 - tm));
+ tm = tm2;
+ }
+ }
+ if (!(frame%epoch_time)) {
+ int s;
+ if (0 != frame) {
+ int tt = epoch_time / 500;
+ if (tt > 15)
+ tt = 15;
+ sleep(tt);
+ }
+
+ for (i = 0; i < npix; i++) {
+ /* equilibrium */
+ r1[i] = 65500;
+ r2[i] = 11;
+ }
+
+ random_colors();
+
+ XSetWindowBackground(display, window, colors[255 % ncolors].pixel);
+ XClearWindow(display, window);
+
+ s = w2 * (height/2) + width/2;
+ radius = get_integer_resource ("radius", "Integer");
+ {
+ int maxr = width/2-2;
+ int maxr2 = height/2-2;
+ if (maxr2 < maxr) maxr = maxr2;
+
+ if (radius < 0)
+ radius = 1 + ((R%10) ? (R%5) : (R % maxr));
+ if (radius > maxr) radius = maxr;
+ }
+ for (i = -radius; i < (radius+1); i++)
+ for (j = -radius; j < (radius+1); j++)
+ r2[s + i + j*w2] = mx - (R&63);
+ reaction = get_integer_resource ("reaction", "Integer");
+ if (reaction < 0 || reaction > 2) reaction = R&1;
+ diffusion = get_integer_resource ("diffusion", "Integer");
+ if (diffusion < 0 || diffusion > 2)
+ diffusion = (R%5) ? ((R%3)?0:1) : 2;
+ if (2 == reaction && 2 == diffusion)
+ reaction = diffusion = 0;
+
+ if (verbose)
+ printf("reaction = %d\ndiffusion = %d\nradius = %d\n",
+ reaction, diffusion, radius);
+ }
+ for (i = 0; i <= width+1; i++) {
+ r1[i] = r1[i + w2 * height];
+ r2[i] = r2[i + w2 * height];
+ r1[i + w2 * (height + 1)] = r1[i + w2];
+ r2[i + w2 * (height + 1)] = r2[i + w2];
+ }
+ for (i = 0; i <= height+1; i++) {
+ r1[w2 * i] = r1[width + w2 * i];
+ r2[w2 * i] = r2[width + w2 * i];
+ r1[w2 * i + width + 1] = r1[w2 * i + 1];
+ r2[w2 * i + width + 1] = r2[w2 * i + 1];
+ }
+ for (i = 0; i < height; i++) {
+ int ii = i + 1;
+ char *q = pix_buf + width * i;
+ short *qq = ((short *) pix_buf) + width * i;
+ long *qqq = ((long *) pix_buf) + width * i;
+ ushort *i1 = r1 + 1 + w2 * ii;
+ ushort *i2 = r2 + 1 + w2 * ii;
+ ushort *o1 = r1b + 1 + w2 * ii;
+ ushort *o2 = r2b + 1 + w2 * ii;
+ for (j = 0; j < width; j++) {
+#if test_pattern_hyper
+ int r1 = (i * j + (frame&127)*frame)&65535;
+#else
+ int uvv, r1 = 0, r2 = 0;
+ switch (diffusion) {
+ case 0:
+ r1 = i1[j] + i1[j+1] + i1[j-1] + i1[j+w2] + i1[j-w2];
+ r1 = r1 / 5;
+ r2 = (i2[j]<<3) + i2[j+1] + i2[j-1] + i2[j+w2] + i2[j-w2];
+ r2 = r2 / 12;
+ break;
+ case 1:
+ r1 = i1[j+1] + i1[j-1] + i1[j+w2] + i1[j-w2];
+ r1 = r1 >> 2;
+ r2 = (i2[j]<<2) + i2[j+1] + i2[j-1] + i2[j+w2] + i2[j-w2];
+ r2 = r2 >> 3;
+ break;
+ case 2:
+ r1 = (i1[j]<<1) + (i1[j+1]<<1) + (i1[j-1]<<1) + i1[j+w2] + i1[j-w2];
+ r1 = r1 >> 3;
+ r2 = (i2[j]<<2) + i2[j+1] + i2[j-1] + i2[j+w2] + i2[j-w2];
+ r2 = r2 >> 3;
+ break;
+ }
+
+ /* John E. Pearson "Complex Patterns in a Simple System"
+ Science, July 1993 */
+
+ uvv = (((r1 * r2) >> bps) * r2) >> bps;
+ switch (reaction) { /* costs 4% */
+ case 0:
+ r1 += 4 * (((28 * (mx-r1)) >> 10) - uvv);
+ r2 += 4 * (uvv - ((80 * r2) >> 10));
+ break;
+ case 1:
+ r1 += 3 * (((27 * (mx-r1)) >> 10) - uvv);
+ r2 += 3 * (uvv - ((80 * r2) >> 10));
+ break;
+ case 2:
+ r1 += 2 * (((28 * (mx-r1)) >> 10) - uvv);
+ r2 += 3 * (uvv - ((80 * r2) >> 10));
+ break;
+ }
+ if (r1 > mx) r1 = mx;
+ if (r2 > mx) r2 = mx;
+ if (r1 < 0) r1 = 0;
+ if (r2 < 0) r2 = 0;
+ o1[j] = r1;
+ o2[j] = r2;
+#endif
+
+ /* this is terrible. here i want to assume ncolors = 256.
+ should lose double indirection */
+
+ if (mapped)
+#if dither_when_mapped
+ q[j] = colors[mc[r1] % ncolors].pixel;
+#else
+ q[j] = colors[(r1>>8) % ncolors].pixel;
+#endif
+ else if (pdepth == 8)
+ q[j] = colors[(r1>>8) % ncolors].pixel;
+ else if (pdepth == 16)
+#if dither_when_mapped
+ qq[j] = colors[mc[r1] % ncolors].pixel;
+#else
+ qq[j] = colors[(r1>>8) % ncolors].pixel;
+#endif
+ else if (pdepth == 32)
+#if dither_when_mapped
+ qqq[j] = colors[mc[r1] % ncolors].pixel;
+#else
+ qqq[j] = colors[(r1>>8) % ncolors].pixel;
+#endif
+ else
+ abort();
+ }
+ }
+ t = r1; r1 = r1b; r1b = t;
+ t = r2; r2 = r2b; r2b = t;
+}
+
+
+/* ------------- xscreensaver rendering -------------- */
+
+
char *progclass = "RD";
char *defaults [] = {
- "RD.background: black", /* to placate SGI */
- "RD.foreground: white",
- "*width: 100",
- "*height: 100",
+ ".background: black",
+ ".foreground: white",
+ "*width: 0", /* tried to use -1 but it complained */
+ "*height: 0",
"*epoch: 40000",
- "*palette: -1",
"*reaction: -1",
"*diffusion: -1",
"*verbose: off",
"*radius: -1",
"*speed: 0.0",
- "*size: 0.66",
- "*delay: 1000",
+ "*size: 1.0",
+ "*delay: 1",
"*colors: -1",
+#ifdef HAVE_XSHM_EXTENSION
+ "*useSHM: True",
+#endif /* HAVE_XSHM_EXTENSION */
0
};
{ "-width", ".width", XrmoptionSepArg, 0 },
{ "-height", ".height", XrmoptionSepArg, 0 },
{ "-epoch", ".epoch", XrmoptionSepArg, 0 },
- { "-palette", ".palette", XrmoptionSepArg, 0 },
{ "-reaction", ".reaction", XrmoptionSepArg, 0 },
{ "-diffusion", ".diffusion", XrmoptionSepArg, 0 },
- { "-verbose", ".verbose", XrmoptionSepArg, 0 },
+ { "-verbose", ".verbose", XrmoptionNoArg, "True" },
{ "-radius", ".radius", XrmoptionSepArg, 0 },
{ "-speed", ".speed", XrmoptionSepArg, 0 },
{ "-size", ".size", XrmoptionSepArg, 0 },
{ "-delay", ".delay", XrmoptionSepArg, 0 },
{ "-ncolors", ".colors", XrmoptionSepArg, 0 },
+#ifdef HAVE_XSHM_EXTENSION
+ { "-shm", ".useSHM", XrmoptionNoArg, "True" },
+ { "-no-shm", ".useSHM", XrmoptionNoArg, "False" },
+#endif /* HAVE_XSHM_EXTENSION */
{ 0, 0, 0, 0 }
};
-#define bps 16
-#define mx ((1<<16)-1)
-/* you can replace integer mults wish shift/adds with these,
- but it doesn't help on my 586 */
-#define x5(n) ((n<<2)+n)
-#define x7(n) ((n<<3)-n)
+static void
+random_colors(void)
+{
+ memset(colors, 0, ncolors*sizeof(*colors));
+ make_smooth_colormap (display, visual, cmap, colors, &ncolors,
+ True, 0, True);
+ if (ncolors <= 2) {
+ mono_p = True;
+ ncolors = 2;
+ colors[0].flags = DoRed|DoGreen|DoBlue;
+ colors[0].red = colors[0].green = colors[0].blue = 0;
+ XAllocColor(display, cmap, &colors[0]);
+ colors[1].flags = DoRed|DoGreen|DoBlue;
+ colors[1].red = colors[1].green = colors[1].blue = 0xFFFF;
+ XAllocColor(display, cmap, &colors[1]);
+ }
-/* why strip bit? */
-#define R (ya_random()&((1<<30)-1))
+ /* Scale it up so that there are exactly 255 colors -- that keeps the
+ animation speed consistent, even when there aren't many allocatable
+ colors, and prevents the -mono mode from looking like static. */
+ if (ncolors != 255) {
+ int i, n = 255;
+ double scale = (double) ncolors / (double) (n+1);
+ XColor *c2 = (XColor *) malloc(sizeof(*c2) * (n+1));
+ for (i = 0; i < n; i++)
+ c2[i] = colors[(int) (i * scale)];
+ free(colors);
+ colors = c2;
+ ncolors = n;
+ }
+
+}
/* should factor into RD-specfic and compute-every-pixel general */
void
GC gc;
XGCValues gcv;
XWindowAttributes xgwa;
- Colormap cmap = 0;
XImage *image;
- int width, height, radius;
int array_width, array_height;
double array_x, array_y;
double array_dx, array_dy;
int w2;
- int frame = 0, epoch_time;
- char *p;
- int vdepth, pdepth;
- ushort *r1, *r2, *r1b, *r2b;
+ char *pd;
+ int vdepth;
int npix;
- int reaction = 0;
- int diffusion = 0;
- int verbose;
- int mapped;
- int *m = 0;
-#if dither_when_mapped
- unsigned char *mc = 0;
-#endif
#ifdef HAVE_XSHM_EXTENSION
- int use_shm = 0;
+ Bool use_shm = get_boolean_resource("useSHM", "Boolean");
XShmSegmentInfo shm_info;
#endif
- int ncolors = 0;
- XColor *colors = 0;
- int delay = get_float_resource ("delay", "Integer");
+ double delay = get_float_resource ("delay", "Float");
+
+ display = dpy;
+ window = win;
+
XGetWindowAttributes (dpy, win, &xgwa);
- width = get_integer_resource ("width", "Integer");
- height = get_integer_resource ("height", "Integer");
+ visual = xgwa.visual;
+ pixack_init(&width, &height);
{
double s = get_float_resource ("size", "Float");
double p = get_float_resource ("speed", "Float");
array_y = (xgwa.height - array_height)/2;
array_dx = p;
array_dy = .31415926 * p;
+
+ /* start in a random direction */
+ if (random() & 1) array_dx = -array_dx;
+ if (random() & 1) array_dy = -array_dy;
+
}
- if (width < 10) width = 10;
- if (height < 10) height = 10;
verbose = get_boolean_resource ("verbose", "Boolean");
npix = (width + 2) * (height + 2);
- epoch_time = get_integer_resource ("epoch", "Integer");
w2 = width + 2;
gcv.function = GXcopy;
gc = XCreateGC(dpy, win, GCFunction, &gcv);
vdepth <= 16 ? 16 :
32);
+ /* Ok, this like, sucks and stuff. There are some XFree86 systems
+ that have depth-24 visuals, that do not accept depth-32 XImages!
+ Which if you ask me is just absurd, since all it would take is
+ for the server to truncate the bits in that case. So, this crap
+ here detects the specific case of: we have chosen depth 32;
+ and the server does not support depth 32. In that case, we
+ try and use depth 16 instead.
+
+ The real fix would be to rewrite this program to deal with
+ depth 24 directly (or even better, arbitrary depths, but that
+ would mean going through the XImage routines instead of messing
+ with the XImage->data directly.)
+
+ jwz, 18-Mar-99: well, the X servers I have access to these days do
+ support 32-deep images on deep visuals, so I no longer have the
+ ability to test this code -- but it was causing problems on the
+ visuals that I do have, and I think that's because I mistakenly
+ wrote `pfv[i].depth' when I meant to write `pfv[i].bits_per_pixel'.
+ The symptom I was seeing was that the grid was 64x64, but the
+ images were being drawn 32x32 -- so there was a black stripe on
+ every other row. Wow, this code sucks so much.
+ */
+ if (pdepth == 32)
+ {
+ int i, pfvc = 0;
+ Bool ok = False;
+ XPixmapFormatValues *pfv = XListPixmapFormats (dpy, &pfvc);
+ for (i = 0; i < pfvc; i++)
+ if (pfv[i].bits_per_pixel == pdepth)
+ ok = True;
+ if (!ok)
+ pdepth = 16;
+ }
+
cmap = xgwa.colormap;
ncolors = get_integer_resource ("colors", "Integer");
mapped = (vdepth <= 8 &&
has_writable_cells(xgwa.screen, xgwa.visual));
- if (!mapped)
- m = (int *) malloc(sizeof(int) * (1<<16));
-#if dither_when_mapped
- else {
+ {
int i, di;
mc = (unsigned char *) malloc(1<<16);
for (i = 0; i < (1<<16); i++) {
- di = (i + (ya_random()&255))>>8;
+ di = (i + (random()&255))>>8;
if (di > 255) di = 255;
mc[i] = di;
}
}
-#endif
- p = malloc(npix * (pdepth == 1 ? 1 : (pdepth / 8)));
- r1 = (ushort *) malloc(sizeof(ushort) * npix);
- r2 = (ushort *) malloc(sizeof(ushort) * npix);
- r1b = (ushort *) malloc(sizeof(ushort) * npix);
- r2b = (ushort *) malloc(sizeof(ushort) * npix);
- if (!p || !r1 || !r2 || !r1b || !r2b) {
+
+ pd = malloc(npix * (pdepth == 1 ? 1 : (pdepth / 8)));
+ if (!pd) {
fprintf(stderr, "not enough memory for %d pixels.\n", npix);
exit(1);
}
-#ifdef HAVE_XSHM_EXTENSION
- if (use_shm) {
- printf("p=%X\n", p);
- free(p);
- image = XShmCreateImage(dpy, xgwa.visual, vdepth,
- ZPixmap, 0, &shm_info, width, height);
- shm_info.shmid = shmget(IPC_PRIVATE,
- image->bytes_per_line * image->height,
- IPC_CREAT | 0777);
- if (shm_info.shmid == -1)
- printf ("shmget failed!");
- shm_info.readOnly = False;
- p = shmat(shm_info.shmid, 0, 0);
- printf("p=%X %d\n", p, image->bytes_per_line);
- XShmAttach(dpy, &shm_info);
- XSync(dpy, False);
- } else
-#endif
- image = XCreateImage(dpy, xgwa.visual, vdepth,
- ZPixmap, 0, p,
- width, height, 8, 0);
+ image = 0;
- while (1) {
- int i, j;
- ushort *t;
-#if test_pattern_hyper
- if (frame&0x100)
- sleep(1);
-#endif
- if (verbose) {
- double tm = 0;
- struct timeval tp;
- struct timezone tzp;
- if (!(frame%100)) {
- double tm2;
- gettimeofday(&tp, &tzp);
- tm2 = tp.tv_sec + tp.tv_usec * 1e-6;
- if (frame > 0)
- printf("fps = %2.4g\n", 100.0 / (tm2 - tm));
- tm = tm2;
- }
+#ifdef HAVE_XSHM_EXTENSION
+ if (use_shm)
+ {
+ image = create_xshm_image(dpy, xgwa.visual, vdepth,
+ ZPixmap, 0, &shm_info, width, height);
+ if (!image)
+ use_shm = False;
+ else
+ {
+ free(pd);
+ pd = image->data;
+ }
}
- if (!(frame%epoch_time)) {
- int s;
- if (0 != frame) {
- int t = epoch_time / 500;
- if (t > 15)
- t = 15;
- sleep(t);
- }
-
- for (i = 0; i < npix; i++) {
- /* equilibrium */
- r1[i] = 65500;
- r2[i] = 11;
- }
-
- memset(colors, 0, ncolors*sizeof(*colors));
- make_smooth_colormap (dpy, xgwa.visual, cmap, colors, &ncolors,
- True, 0, True);
- if (ncolors <= 2) {
- mono_p = True;
- ncolors = 2;
- colors[0].flags = DoRed|DoGreen|DoBlue;
- colors[0].red = colors[0].green = colors[0].blue = 0;
- XAllocColor(dpy, cmap, &colors[0]);
- colors[1].flags = DoRed|DoGreen|DoBlue;
- colors[1].red = colors[1].green = colors[1].blue = 0xFFFF;
- XAllocColor(dpy, cmap, &colors[1]);
- }
+#endif /* HAVE_XSHM_EXTENSION */
- /* Scale it up so that there are exactly 255 colors -- that keeps the
- animation speed consistent, even when there aren't many allocatable
- colors, and prevents the -mono mode from looking like static. */
- if (ncolors != 255) {
- int i, n = 255;
- double scale = (double) ncolors / (double) (n+1);
- XColor *c2 = (XColor *) malloc(sizeof(*c2) * (n+1));
- for (i = 0; i < n; i++)
- c2[i] = colors[(int) (i * scale)];
- free(colors);
- colors = c2;
- ncolors = n;
- }
-
-
- XSetWindowBackground(dpy, win, colors[255 % ncolors].pixel);
- XClearWindow(dpy, win);
-
- s = w2 * height/2 + width/2;
- radius = get_integer_resource ("radius", "Integer");
- if (radius < 0)
- radius = 1 + ((R%10) ? (R%5) : (R % (width/2-2)));
- for (i = -radius; i < (radius+1); i++)
- for (j = -radius; j < (radius+1); j++)
- r2[s + i + j*w2] = mx - (R&63);
- reaction = get_integer_resource ("reaction", "Integer");
- if (reaction < 0 || reaction > 2) reaction = R&1;
- diffusion = get_integer_resource ("diffusion", "Integer");
- if (diffusion < 0 || diffusion > 2)
- diffusion = (R%5) ? ((R%3)?0:1) : 2;
- if (2 == reaction && 2 == diffusion)
- reaction = diffusion = 0;
-
-/* if (verbose)
- printf("reaction = %d\ndiffusion = %d\n"
- "palette = %d\nradius = %d\n",
- reaction, diffusion, palette, radius);
-*/
- }
- for (i = 0; i <= width+1; i++) {
- r1[i] = r1[i + w2 * height];
- r2[i] = r2[i + w2 * height];
- r1[i + w2 * (height + 1)] = r1[i + w2];
- r2[i + w2 * (height + 1)] = r2[i + w2];
- }
- for (i = 0; i <= height+1; i++) {
- r1[w2 * i] = r1[width + w2 * i];
- r2[w2 * i] = r2[width + w2 * i];
- r1[w2 * i + width + 1] = r1[w2 * i + 1];
- r2[w2 * i + width + 1] = r2[w2 * i + 1];
+ if (!image)
+ {
+ image = XCreateImage(dpy, xgwa.visual, vdepth,
+ ZPixmap, 0, pd,
+ width, height, 8, 0);
}
- for (i = 0; i < height; i++) {
- int ii = i + 1;
- char *q = p + width * i;
- short *qq = ((short *) p) + width * i;
- long *qqq = ((long *) p) + width * i;
- ushort *i1 = r1 + 1 + w2 * ii;
- ushort *i2 = r2 + 1 + w2 * ii;
- ushort *o1 = r1b + 1 + w2 * ii;
- ushort *o2 = r2b + 1 + w2 * ii;
- for (j = 0; j < width; j++) {
-#if test_pattern_hyper
- int r1 = (i * j + (frame&127)*frame)&65535;
-#else
- int uvv, r1 = 0, r2 = 0;
- switch (diffusion) {
- case 0:
- r1 = i1[j] + i1[j+1] + i1[j-1] + i1[j+w2] + i1[j-w2];
- r1 = r1 / 5;
- r2 = (i2[j]<<3) + i2[j+1] + i2[j-1] + i2[j+w2] + i2[j-w2];
- r2 = r2 / 12;
- break;
- case 1:
- r1 = i1[j+1] + i1[j-1] + i1[j+w2] + i1[j-w2];
- r1 = r1 >> 2;
- r2 = (i2[j]<<2) + i2[j+1] + i2[j-1] + i2[j+w2] + i2[j-w2];
- r2 = r2 >> 3;
- break;
- case 2:
- r1 = (i1[j]<<1) + (i1[j+1]<<1) + (i1[j-1]<<1) + i1[j+w2] + i1[j-w2];
- r1 = r1 >> 3;
- r2 = (i2[j]<<2) + i2[j+1] + i2[j-1] + i2[j+w2] + i2[j-w2];
- r2 = r2 >> 3;
- break;
- }
- uvv = (((r1 * r2) >> bps) * r2) >> bps;
- switch (reaction) { /* costs 4% */
- case 0:
- r1 += 4 * (((28 * (mx-r1)) >> 10) - uvv);
- r2 += 4 * (uvv - ((80 * r2) >> 10));
- break;
- case 1:
- r1 += 3 * (((27 * (mx-r1)) >> 10) - uvv);
- r2 += 3 * (uvv - ((80 * r2) >> 10));
- break;
- case 2:
- r1 += 2 * (((28 * (mx-r1)) >> 10) - uvv);
- r2 += 3 * (uvv - ((80 * r2) >> 10));
- break;
- }
- if (r1 > mx) r1 = mx;
- if (r2 > mx) r2 = mx;
- if (r1 < 0) r1 = 0;
- if (r2 < 0) r2 = 0;
- o1[j] = r1;
- o2[j] = r2;
-#endif
- if (mapped)
-#if dither_when_mapped
- q[j] = colors[mc[r1] % ncolors].pixel;
-#else
- q[j] = colors[(r1>>8) % ncolors].pixel;
-#endif
- else if (pdepth == 8)
- q[j] = colors[(r1>>8) % ncolors].pixel;
- else if (pdepth == 16)
- qq[j] = colors[(r1>>8) % ncolors].pixel;
- else if (pdepth == 32)
- qqq[j] = colors[(r1>>8) % ncolors].pixel;
- else
- abort();
- }
- }
- t = r1; r1 = r1b; r1b = t;
- t = r2; r2 = r2b; r2b = t;
+ while (1) {
+ Bool bump = False;
+
+ int i, j;
+ pixack_frame(pd);
for (i = 0; i < array_width; i += width)
for (j = 0; j < array_height; j += height)
#ifdef HAVE_XSHM_EXTENSION
if (use_shm)
- XShmPutImage(dpy, win, gc, image, 0, 0, i, j,
+ XShmPutImage(dpy, win, gc, image, 0, 0, i+array_x, j+array_y,
width, height, False);
else
#endif
- XPutImage(dpy, win, gc, image, 0, 0, i+array_x, j+array_y, width, height);
+ XPutImage(dpy, win, gc, image, 0, 0, i+array_x, j+array_y,
+ width, height);
array_x += array_dx;
array_y += array_dy;
if (array_x < 0) {
array_x = 0;
array_dx = -array_dx;
+ bump = True;
} else if (array_x > (xgwa.width - array_width)) {
array_x = (xgwa.width - array_width);
array_dx = -array_dx;
+ bump = True;
}
if (array_y < 0) {
array_y = 0;
array_dy = -array_dy;
+ bump = True;
} else if (array_y > (xgwa.height - array_height)) {
array_y = (xgwa.height - array_height);
array_dy = -array_dy;
+ bump = True;
}
+
+ if (bump) {
+ if (random() & 1) {
+ double swap = array_dx;
+ array_dx = array_dy;
+ array_dy = swap;
+ }
+ }
+
frame++;
XSync(dpy, False);
+ screenhack_handle_events (dpy);
if (delay > 0)
- usleep(delay);
+ usleep(1000 * delay);
}
}