X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Frd-bomb.c;h=dd5253bc259974f74f6cb4dcee38824b12328b5c;hb=3f438031d610c7e15fd33876a879b97e290e05fb;hp=9dfe8d38ec6388558ad73f8a04bfdc2bec8927c4;hpb=5b7bc6e70fb439cf4c4bf771ae9f94077fe4fe08;p=xscreensaver diff --git a/hacks/rd-bomb.c b/hacks/rd-bomb.c index 9dfe8d38..dd5253bc 100644 --- a/hacks/rd-bomb.c +++ b/hacks/rd-bomb.c @@ -1,5 +1,5 @@ -/* xscreensaver, Copyright (c) 1992, 1995, 1997 - * Jamie Zawinski +/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 1999, 2003 + * Jamie Zawinski * * reaction/diffusion textures * Copyright (c) 1997 Scott Draves spot@transmeta.com @@ -21,36 +21,297 @@ #include #include "screenhack.h" +#include -/* why doesn't this work??? */ #ifdef HAVE_XSHM_EXTENSION -#include -#include -#include +# 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; -- crashes on Alpha */ + int *qqq = ((int *) 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", "*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 }; @@ -66,19 +327,46 @@ XrmOptionDescRec options [] = { { "-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 @@ -87,38 +375,28 @@ screenhack (Display *dpy, Window win) 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"); @@ -137,12 +415,14 @@ screenhack (Display *dpy, Window win) 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); @@ -157,6 +437,40 @@ screenhack (Display *dpy, Window win) 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"); @@ -174,258 +488,96 @@ screenhack (Display *dpy, Window win) 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; - 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; - } +#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\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]; + 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); } }