+
+/* 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 t = epoch_time / 500;
+ if (t > 15)
+ t = 15;
+ sleep(t);
+ }
+
+ 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 -------------- */
+
+