From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / rd-bomb.c
index c4b56391d2044ab9edd07a7953e67d06ab21be9e..33cb602a1658a0d189d3a1382f8c5b38158d0699 100644 (file)
@@ -1,5 +1,4 @@
-/* xscreensaver, Copyright (c) 1992, 1995, 1997, 1998, 1999, 2003, 2006
- *  Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1992-2014 Jamie Zawinski <jwz@jwz.org>
  *
  *  reaction/diffusion textures
  *  Copyright (c) 1997 Scott Draves spot@transmeta.com
 #include <math.h>
 
 #include "screenhack.h"
-
-#ifdef HAVE_XSHM_EXTENSION
-# include "xshm.h"
-#endif /* HAVE_XSHM_EXTENSION */
+#include "xshm.h"
 
 /* costs ~6% speed */
 #define dither_when_mapped 1
@@ -33,7 +29,6 @@ struct state {
   Display *dpy;
   Window window;
 
-  int verbose;
   int ncolors;
   XColor *colors;
   Visual *visual;
@@ -54,10 +49,7 @@ struct state {
   char *pd;
   int array_width, array_height;
 
-#ifdef HAVE_XSHM_EXTENSION
-  Bool use_shm;
   XShmSegmentInfo shm_info;
-#endif
 
   GC gc;
   XImage *image;
@@ -87,22 +79,29 @@ static void random_colors(struct state *st);
 
 /* why strip bit? */
 #define R (random()&((1<<30)-1))
+#define BELLRAND(x) (((random()%(x)) + (random()%(x)) + (random()%(x)))/3)
 
 /* returns number of pixels that the pixack produces.  called once. */
 static void
 pixack_init(struct state *st, int *size_h, int *size_v) 
 {
-  int sz_base;
-  st->width = get_integer_resource (st->dpy, "width", "Integer");
+  st->width  = get_integer_resource (st->dpy, "width",  "Integer");
   st->height = get_integer_resource (st->dpy, "height", "Integer");
-  sz_base = 80 + (R%40);
-  if (st->width <= 0) st->width = (R%20) ? sz_base : (28 + R%10);
-  if (st->height <= 0) st->height = (R%20) ? sz_base : (28 + R%10);
+
+  if (st->width <= 0 && st->height <= 0 && (R & 1))
+    st->width = st->height = 64 + BELLRAND(512);
+
+  if (st->width  <= 0) st->width  = 64 + BELLRAND(512);
+  if (st->height <= 0) st->height = 64 + BELLRAND(512);
+
+  if (st->width  > st->xgwa.width)  st->width  = st->xgwa.width;
+  if (st->height > st->xgwa.height) st->height = st->xgwa.height;
 
   /* jwz: when (and only when) XSHM is in use on an SGI 8-bit visual,
      we get shear unless st->width is a multiple of 4.  I don't understand
      why.  This is undoubtedly the wrong fix... */
-  st->width &= ~0x7;
+  if (visual_depth (st->xgwa.screen, st->xgwa.visual) == 8)
+    st->width &= ~0x7;
 
   /* don't go there */
   if (st->width < 10) st->width = 10;
@@ -137,31 +136,9 @@ pixack_frame(struct state *st, char *pix_buf)
   if (st->frame&0x100)
     sleep(1);
 #endif
-  if (st->verbose) {
-    double tm = 0;
-    struct timeval tp;
-    if (!(st->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 (st->frame > 0)
-       printf("fps = %2.4g\n", 100.0 / (tm2 - tm));
-      tm = tm2;
-    }
-  }
+
   if (!(st->frame%st->epoch_time)) {
     int s;
-    if (0 != st->frame) {
-      int tt = st->epoch_time / 500;
-      if (tt > 15)
-       tt = 15;
-      /*sleep(tt);*/
-    }
          
     for (i = 0; i < st->npix; i++) {
       /* equilibrium */
@@ -195,10 +172,6 @@ pixack_frame(struct state *st, char *pix_buf)
       st->diffusion = (R%5) ? ((R%3)?0:1) : 2;
     if (2 == st->reaction && 2 == st->diffusion)
       st->reaction = st->diffusion = 0;
-      
-    if (st->verbose)
-      printf("reaction = %d\ndiffusion = %d\nradius = %d\n",
-            st->reaction, st->diffusion, st->radius);
   }
   for (i = 0; i <= st->width+1; i++) {
     st->r1[i] = st->r1[i + w2 * st->height];
@@ -251,7 +224,9 @@ pixack_frame(struct state *st, char *pix_buf)
       /* John E. Pearson "Complex Patterns in a Simple System"
         Science, July 1993 */
 
-      uvv = (((r1 * r2) >> bps) * r2) >> bps;
+      /* uvv = (((r1 * r2) >> bps) * r2) >> bps; */
+      /* avoid signed integer overflow */
+      uvv = ((((r1 >> 1)* r2) >> bps) * r2) >> (bps - 1);
       switch (st->reaction) {  /* costs 4% */
       case 0:
        r1 += 4 * (((28 * (mx-r1)) >> 10) - uvv);
@@ -311,21 +286,24 @@ pixack_frame(struct state *st, char *pix_buf)
 static const char *rd_defaults [] = {
   ".background:        black",
   ".foreground:        white",
+  "*fpsSolid:  true",
   "*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:      1.0",
-  "*delay:     20000",
-  "*colors:    -1",
+  "*delay:     30000",
+  "*colors:    255",
 #ifdef HAVE_XSHM_EXTENSION
   "*useSHM:    True",
 #else
   "*useSHM:    False",
+#endif
+#ifdef HAVE_MOBILE
+  "*ignoreRotation: True",
 #endif
   0
 };
@@ -336,7 +314,6 @@ static XrmOptionDescRec rd_options [] = {
   { "-epoch",          ".epoch",       XrmoptionSepArg, 0 },
   { "-reaction",       ".reaction",    XrmoptionSepArg, 0 },
   { "-diffusion",      ".diffusion",   XrmoptionSepArg, 0 },
-  { "-verbose",                ".verbose",     XrmoptionNoArg, "True" },
   { "-radius",         ".radius",      XrmoptionSepArg, 0 },
   { "-speed",          ".speed",       XrmoptionSepArg, 0 },
   { "-size",           ".size",        XrmoptionSepArg, 0 },
@@ -352,7 +329,8 @@ static void
 random_colors(struct state *st)
 {
   memset(st->colors, 0, st->ncolors*sizeof(*st->colors));
-  make_smooth_colormap (st->dpy, st->visual, st->cmap, st->colors, &st->ncolors,
+  make_smooth_colormap (st->xgwa.screen, st->visual, st->cmap,
+                        st->colors, &st->ncolors,
                        True, 0, True);
   if (st->ncolors <= 2) {
     mono_p = True;
@@ -388,7 +366,6 @@ rd_init (Display *dpy, Window win)
 {
   struct state *st = (struct state *) calloc (1, sizeof(*st));
   XGCValues gcv;
-  int w2;
   int vdepth;
 
   st->dpy = dpy;
@@ -396,10 +373,6 @@ rd_init (Display *dpy, Window win)
 
   st->delay = get_integer_resource (st->dpy, "delay", "Float");
 
-#ifdef HAVE_XSHM_EXTENSION
-  st->use_shm = get_boolean_resource(st->dpy, "useSHM", "Boolean");
-#endif
-
   XGetWindowAttributes (st->dpy, win, &st->xgwa);
   st->visual = st->xgwa.visual;
   pixack_init(st, &st->width, &st->height);
@@ -427,9 +400,7 @@ rd_init (Display *dpy, Window win)
     if (random() & 1) st->array_dy = -st->array_dy;
 
   }
-  st->verbose = get_boolean_resource (st->dpy, "verbose", "Boolean");
   st->npix = (st->width + 2) * (st->height + 2);
-  w2 = st->width + 2;
 /*  gcv.function = GXcopy;*/
   st->gc = XCreateGC(st->dpy, win, 0 /*GCFunction*/, &gcv);
   vdepth = visual_depth(DefaultScreenOfDisplay(st->dpy), st->xgwa.visual);
@@ -480,7 +451,7 @@ rd_init (Display *dpy, Window win)
   st->cmap = st->xgwa.colormap;
   st->ncolors = get_integer_resource (st->dpy, "colors", "Integer");
 
-  if (st->ncolors <= 0) {
+  if (st->ncolors <= 0 || st->ncolors >= 255) {
     if (vdepth > 8)
       st->ncolors = 2047;
     else
@@ -504,35 +475,9 @@ rd_init (Display *dpy, Window win)
     }
   }
 
-  st->pd = malloc(st->npix * (st->pdepth == 1 ? 1 : (st->pdepth / 8)));
-  if (!st->pd) {
-    fprintf(stderr, "not enough memory for %d pixels.\n", st->npix);
-    exit(1);
-  }
-
-  st->image = 0;
-
-#ifdef HAVE_XSHM_EXTENSION
-  if (st->use_shm)
-    {
-      st->image = create_xshm_image(st->dpy, st->xgwa.visual, vdepth,
-                               ZPixmap, 0, &st->shm_info, st->width, st->height);
-      if (!st->image)
-       st->use_shm = False;
-      else
-       {
-         free(st->pd);
-         st->pd = st->image->data;
-       }
-    }
-#endif /* HAVE_XSHM_EXTENSION */
-
-  if (!st->image)
-    {
-      st->image = XCreateImage(st->dpy, st->xgwa.visual, vdepth,
-                          ZPixmap, 0, st->pd,
-                          st->width, st->height, 8, 0);
-    }
+  st->image = create_xshm_image(st->dpy, st->xgwa.visual, vdepth,
+                                ZPixmap, &st->shm_info, st->width, st->height);
+  st->pd = st->image->data;
 
   return st;
 }
@@ -547,14 +492,8 @@ rd_draw (Display *dpy, Window win, void *closure)
   pixack_frame(st, st->pd);
   for (i = 0; i < st->array_width; i += st->width)
     for (j = 0; j < st->array_height; j += st->height)
-#ifdef HAVE_XSHM_EXTENSION
-      if (st->use_shm)
-        XShmPutImage(st->dpy, st->window, st->gc, st->image, 0, 0, i+st->array_x, j+st->array_y,
-                     st->width, st->height, False);
-      else
-#endif
-        XPutImage(st->dpy, win, st->gc, st->image, 0, 0, i+st->array_x, j+st->array_y,
-                  st->width, st->height);
+      put_xshm_image(st->dpy, st->window, st->gc, st->image, 0, 0, i+st->array_x, j+st->array_y,
+                     st->width, st->height, &st->shm_info);
 
   st->array_x += st->array_dx;
   st->array_y += st->array_dy;