home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3424 < prev    next >
Internet Message Format  |  1991-05-25  |  14KB

  1. From: cheeks@arsenic..eds.com (Mark Costlow)
  2. Newsgroups: alt.sources
  3. Subject: Plasma program for X11
  4. Message-ID: <1991May26.023640.4615@edsr.eds.com>
  5. Date: 26 May 91 02:36:40 GMT
  6.  
  7. This is a program for generating/displaying plasma cloud images for X11.  
  8. Here's part of the README:
  9.  
  10. This is plasma.  It implements "plasma clouds" with X11.  It's not very
  11. sophisticated ... I just saw jjensen@dsg4.dse.beckman.com (John Jensen)'s
  12. post in alt.fractals and coded up his ideas (and used some of his code) with
  13. my Xlib skeleton which I use for prototyping graphics ideas.  It does
  14. colormap cycling, and it lets you mess with a few of the parameters.
  15.  
  16. Enjoy ...
  17.  
  18. Mark
  19. cheeks@edsr.eds.com    or     ...uunet!edsr!cheeks
  20.  
  21. #---------------------------------- cut here ----------------------------------
  22. # This is a shell archive.  Remove anything before this line,
  23. # then unpack it by saving it in a file and typing "sh file".
  24. #
  25. # Wrapped by Mark Costlow <cheeks@argon> on Sat May 25 20:30:25 1991
  26. #
  27. # This archive contains:
  28. #    README        Makefile    plasma.c    
  29. #
  30. # Existing files will not be overwritten.
  31. # Error checking via wc(1) will be performed.
  32.  
  33. LANG=""; export LANG
  34. PATH=/bin:/usr/bin:$PATH; export PATH
  35.  
  36. if test -f README
  37. then
  38.     echo Ok to overwrite existing file README\?
  39.     read answer
  40.     case "$answer" in
  41.     [yY]*)    echo Proceeding;;
  42.     *)    echo Aborting; exit 1;;
  43.     esac
  44.     rm -f README
  45.     if test -f README
  46.     then
  47.         echo Error: could not remove README, aborting
  48.         exit 1
  49.     fi
  50. fi
  51. echo x - README
  52. cat >README <<'@EOF'
  53. This is plasma.  It implements "plasma clouds" with X11.  It's not very
  54. sophisticated ... I just saw jjensen@dsg4.dse.beckman.com (John Jensen)'s
  55. post in alt.fractals and coded up his ideas (and used some of his code) with
  56. my Xlib skeleton which I use for prototyping graphics ideas.  It does
  57. colormap cycling, and it lets you mess with a few of the parameters.
  58.  
  59. It definitely works with sparcs under SunOS 4.1.x and 8 bit displays.  My
  60. skeleton runs on HPs under hpux as well, even with those gnarly 6-bit
  61. displays, but I haven't tested it with this program.
  62.  
  63. I don't really have time to "maintain" this thing ... I'm just throwing it
  64. out since it's kinda cute.  I'll fix bugs as time permits though, and I
  65. would like to hear about changes or improvements (like getting it to use
  66. the default color map and running on the root window, etc).  It is hereby
  67. placed in the public domain ... give it away, sell it, whatever.  I'd
  68. appreciate it if my name was left on it though.
  69.  
  70. Mark Costlow
  71. cheeks@edsr.eds.com    or     ...uunet!edsr!cheeks
  72. @EOF
  73. set `wc -lwc <README`
  74. if test $1$2$3 != 191781038
  75. then
  76.     echo ERROR: wc results of README are $* should be 19 178 1038
  77. fi
  78.  
  79. chmod 664 README
  80.  
  81. if test -f Makefile
  82. then
  83.     echo Ok to overwrite existing file Makefile\?
  84.     read answer
  85.     case "$answer" in
  86.     [yY]*)    echo Proceeding;;
  87.     *)    echo Aborting; exit 1;;
  88.     esac
  89.     rm -f Makefile
  90.     if test -f Makefile
  91.     then
  92.         echo Error: could not remove Makefile, aborting
  93.         exit 1
  94.     fi
  95. fi
  96. echo x - Makefile
  97. cat >Makefile <<'@EOF'
  98. CC = gcc
  99. CFLAGS = -g
  100.  
  101. .c.o:
  102.     $(CC) $(CFLAGS) -c $<
  103.  
  104.  
  105. PROGS =  plasma
  106. all: $(PROGS)
  107.  
  108. plasma: plasma.o
  109.     $(CC) $(CFLAGS) -o plasma plasma.o -lX11 -lm
  110.  
  111. clean:
  112.     rm -f core *.o $(PROGS)
  113. @EOF
  114. set `wc -lwc <Makefile`
  115. if test $1$2$3 != 1531180
  116. then
  117.     echo ERROR: wc results of Makefile are $* should be 15 31 180
  118. fi
  119.  
  120. chmod 664 Makefile
  121.  
  122. if test -f plasma.c
  123. then
  124.     echo Ok to overwrite existing file plasma.c\?
  125.     read answer
  126.     case "$answer" in
  127.     [yY]*)    echo Proceeding;;
  128.     *)    echo Aborting; exit 1;;
  129.     esac
  130.     rm -f plasma.c
  131.     if test -f plasma.c
  132.     then
  133.         echo Error: could not remove plasma.c, aborting
  134.         exit 1
  135.     fi
  136. fi
  137. echo x - plasma.c
  138. cat >plasma.c <<'@EOF'
  139. /*
  140.  *  plasma.c  -- generate/display plasma clouds with X11.  It was written in
  141.  *               about an hour ... and the code shows it :-).
  142.  *
  143.  *  Mark Costlow
  144.  *  cheeks@edsr.eds.com
  145.  *  May 25, 1991
  146.  */
  147. #include <stdio.h>
  148. #include <math.h>
  149. #include <ctype.h>
  150.  
  151. /* X-windows includes */
  152. #include <X11/Xos.h>
  153. #include <X11/Xatom.h>
  154. #include <X11/Xlib.h>
  155. #include <X11/Xutil.h>
  156. #include <X11/cursorfont.h>
  157.  
  158. typedef unsigned char byte;
  159. double drand48();
  160.  
  161. Display         *display;
  162. char            win_name[64];
  163. Visual          *visual = NULL;
  164. Status          status;
  165. unsigned long   wp, bp;     /* pixel values for black & white */
  166. int screen, nplanes, ncolors;
  167.  
  168. XEvent         event;
  169. XExposeEvent   *expose;
  170. XSetWindowAttributes attrib;
  171.  
  172. GC           gc;
  173. XGCValues    gc_val;
  174. XSizeHints   sizehints;
  175. Window       imagewin;        /* window ID for image */
  176. XImage       *image = NULL;
  177. Colormap     *cmaps;
  178.  
  179. double Futz = 2.0;       /* Global scale of random perturbations. */
  180. int usedist = 1;         /* Use distance to scale perturbations.  */
  181. int sleep_delay = 50000; /* speed of colormap cyling.             */
  182.  
  183. int global_x, global_y;
  184. byte *buf;
  185. #define BUF(a,b) buf[(global_y * b) + a]
  186. #define NUMCOLORS 255
  187.  
  188. void MakeColormaps(int nplanes)
  189. {
  190.   XColor colors[256];
  191.   int i, j, mask, tempcolor;
  192.   Colormap cmap;
  193.   double step, f;
  194.       
  195.   fprintf(stderr, "Building color maps . . . ");
  196.   fflush(stderr);
  197.   
  198.   ncolors = 1 << nplanes;
  199.   
  200.   cmaps = (Colormap *) malloc(ncolors * sizeof(Colormap));
  201.   
  202.   step = (double) ( (M_PI_4 * (double)nplanes) / (double) ncolors);
  203.   f = M_PI; /* + M_PI_2; */
  204. #define MAXI 65535
  205.  
  206.   for (i = 0; i < ncolors; i++) 
  207.     {
  208.       double wank = MAXI / 2.0;
  209.       double sin(double);
  210.       
  211. #define PLAIN
  212.  
  213.       colors[i].pixel = i;
  214.       colors[i].flags = DoRed | DoGreen | DoBlue;
  215. #ifdef PLAIN
  216.       colors[i].red   = (int)((wank * sin(f)) + wank);
  217.       colors[i].green = (int)((wank * sin(f + M_PI)) + wank);
  218.       colors[i].blue  = (int)((wank * sin(f + M_PI + M_PI_2)) + wank);
  219. #else
  220.       colors[i].red   = (int)((wank * sin(f)) + wank);
  221.       colors[i].green = (int)((wank * sin(f + M_PI_4)) + wank);
  222.       colors[i].blue  = (int)((wank * sin(f + M_PI_2)) + wank);
  223. #endif
  224.       f += step;
  225.     }
  226.   
  227.   for (j = 0; j < ncolors; j++)
  228.     {
  229.       tempcolor = colors[0].pixel;
  230.       for (i = 0; i < ncolors - 1; i++)
  231.     colors[i].pixel = colors[i+1].pixel;
  232.       colors[ncolors-1].pixel = tempcolor;
  233.       
  234.       cmaps[j] = XCreateColormap(display, RootWindow(display, screen), visual, 
  235.                  AllocAll);
  236.       XStoreColors(display, cmaps[j], colors, ncolors);
  237.     }      
  238.   fprintf(stderr, "Done\n");
  239.   fflush(stderr);
  240. }
  241.  
  242. void CycleColormap()
  243. {
  244.   static int current_map = 0;
  245.  
  246.   XSetWindowColormap(display, imagewin, cmaps[current_map++]);
  247.   current_map = (current_map % ncolors);
  248.   XSync(display, False);
  249. }  
  250.   
  251.  
  252. void InitX(char *disp, int x, int y)
  253. {
  254.   int i, j;
  255.   
  256.   strcpy(win_name, "Plasma");
  257.   
  258.   /*  
  259.    *  Open the connection to the X11 server and set defaults 
  260.    */
  261.   if ((display = XOpenDisplay(disp)) == NULL) 
  262.     {
  263.       fprintf(stderr,"Could not open display.\n");
  264.       exit(1); 
  265.     }
  266.   screen = XDefaultScreen(display);
  267.   visual = XDefaultVisual(display, screen);
  268.   nplanes = XDisplayPlanes(display, screen);
  269.  
  270.   bp = BlackPixel(display, screen);
  271.   wp = WhitePixel(display, screen);
  272.  
  273.   /*
  274.    * Set window manager hints
  275.    */
  276.   sizehints.flags = PPosition | PSize | PMinSize | PMaxSize;
  277.   sizehints.width = sizehints.min_width = x;
  278.   sizehints.max_width = x;
  279.   sizehints.height = sizehints.min_height = y;
  280.   sizehints.max_height = x;
  281.   sizehints.x = 0;
  282.   sizehints.y = 0;
  283.   
  284.   MakeColormaps(nplanes);
  285.   attrib.background_pixel = wp;
  286.   attrib.border_pixel     = bp;
  287.   attrib.event_mask       = (ExposureMask | LeaveWindowMask | 
  288.                  ButtonPressMask | ButtonReleaseMask |
  289.                  ColormapChangeMask | Button1MotionMask |
  290.                  EnterWindowMask);
  291.   attrib.cursor = XCreateFontCursor(display, XC_top_left_arrow);
  292.   
  293.   /*
  294.    * Create the window.
  295.    */
  296.   imagewin = XCreateWindow(display, RootWindow(display, screen), 0, 0,
  297.                x, y, 5, XDefaultDepth(display, screen),
  298.                InputOutput, visual, 
  299.                (CWBackPixel|CWEventMask|CWCursor|CWBorderPixel), 
  300.                &attrib);
  301.  
  302.   /* 
  303.    * Install properties for the window.
  304.    */
  305.   XSetStandardProperties(display, imagewin, win_name, win_name, NULL,
  306.              NULL, NULL, &sizehints);
  307.   XSetIconName(display, imagewin, "Plasma");
  308.  
  309.   /*
  310.    *  Install the colormap
  311.    */
  312.   XSetWindowColormap(display, imagewin, cmaps[0]);
  313.  
  314.  
  315. /* #define DEBUG */
  316. #ifdef DEBUG
  317.   /*
  318.    *  See what's in the colormap
  319.    */
  320.   for (j = 0; j < (1<<nplanes); j++)
  321.     {
  322.       for (i=0; i < (1 << nplanes); i++) 
  323.     {
  324.       XColor qcolor;
  325.       
  326.       qcolor.pixel = (u_long)i;
  327.       XQueryColor(display, cmaps[j], &qcolor);
  328.       fprintf(stderr,"color[%2d]: pix %3u r= %5u g= %5u b= %5u\n",i,
  329.           qcolor.pixel, qcolor.red, qcolor.green, qcolor.blue);
  330.     }
  331.     }
  332.   fprintf(stderr, "\n\n");
  333. #endif
  334.   
  335.   /* 
  336.    * Now finally map the window ... 
  337.    */
  338.   XMapWindow(display, imagewin);
  339.  
  340.   /* 
  341.    * Create a Graphics Context.
  342.    */
  343.   gc_val.foreground = bp;
  344.   gc_val.background = wp;
  345.   gc = XCreateGC(display, imagewin, GCForeground | GCBackground , &gc_val);
  346.   
  347.   /* 
  348.    * select which input events to honor  
  349.    */
  350.   XSelectInput(display, imagewin, (ExposureMask | KeyPressMask));
  351.  
  352.   /* 
  353.    * Wait for first expose event
  354.    */
  355.   XNextEvent(display, &event);
  356.   while (event.type != Expose)
  357.     {
  358.       XNextEvent(display, &event);
  359.     } 
  360. }  
  361.  
  362.  
  363. show_pic(byte *buf, int x, int y) 
  364. {
  365.   char  ch, tmp[80];
  366.   static int ngen = 0;
  367.   
  368.   image = XCreateImage(display, visual, nplanes, ZPixmap, 0, (char *)buf, 
  369.                x, y, 8, 0);
  370.  
  371.   XPutImage(display, imagewin, gc, image, 0, 0, 0, 0, x, y);
  372.   XSync(display, False);
  373. }
  374.  
  375. /* 
  376.  * Enter infinite loop to sevice events.
  377.  */
  378. void manage_window()
  379. {
  380.   int Finished;
  381.   XKeyEvent *keypress;
  382.   KeySym keysym;
  383.   char keybuf[64];
  384.   XComposeStatus cstat;
  385.   
  386.   Finished = 0;
  387.   expose = (XExposeEvent *)&event;
  388.   keypress = (XKeyEvent *)&event;
  389.  
  390.   while (!Finished) 
  391.     {
  392.       if (XPending(display))
  393.     {
  394.       XNextEvent(display, &event);
  395.       switch ((int)event.type) 
  396.         {
  397.         case Expose:
  398.           if (expose->x % 4 != 0) 
  399.         {
  400.           expose->x -= (expose->x % 4);
  401.           expose->width += (expose->x % 4);
  402.         }
  403.           if (expose->width % 4 != 0) 
  404.         expose->width += 4 - (expose->width % 4);
  405.           XPutImage(display, imagewin, gc, image, expose->x, expose->y, 
  406.             expose->x, expose->y, expose->width, expose->height);
  407.           break;
  408.         case ButtonPress:
  409.           Finished = 1;
  410.           break;
  411.         case KeyPress:
  412.           XLookupString(keypress, keybuf, sizeof(keybuf), &keysym, &cstat);
  413.           if(*keybuf == 'q' || *keybuf == 'Q')
  414.         Finished = 1;
  415.           break;
  416.         default:
  417.           break;
  418.         }
  419.     }
  420.       usleep(sleep_delay);
  421.       CycleColormap();
  422.     }
  423. }
  424.  
  425. adjust(int xa, int ya, int x, int y, int xb, int yb)
  426. {
  427.   int d;
  428.   double v;
  429.  
  430.   if (usedist)
  431.     d = abs(xa - xb) + abs(ya - yb);
  432.   else
  433.     d = 1.0;
  434.   
  435.   v = (BUF(xa, ya) + BUF(xb, yb)) / 2 + (drand48() - 0.5) * d * Futz;
  436.  
  437.   if (v < 1.0)
  438.     v = 1.0;
  439.   else if (v > (double)NUMCOLORS)
  440.     v = (double)NUMCOLORS;
  441.   BUF(x, y) = (int)v;
  442. }
  443.  
  444. subdivide(int x1, int y1, int x2, int y2)
  445. {
  446.   int x, y, v;
  447.  
  448.   if ((x2 - x1 > 1) || (y2 - y1 > 1)) 
  449.     {
  450.       x = (x1 + x2) / 2;
  451.       y = (y1 + y2) / 2;
  452.  
  453.       if (!BUF(x,y1))
  454.       adjust(x1, y1, x, y1, x2, y1);
  455.       if (!BUF(x2,y))
  456.       adjust(x2, y1, x2, y, x2, y2);
  457.       if (!BUF(x,y2))
  458.       adjust(x1, y2, x, y2, x2, y2);
  459.       if (!BUF(x1,y))
  460.       adjust(x1, y1, x1, y, x1, y2);
  461.       
  462.       if (!BUF(x, y)) 
  463.     {
  464.       v = (BUF(x1, y1) + BUF(x2, y1) + BUF(x2, y2) + BUF(x1, y2)) / 4;
  465.       if (v < 1)
  466.         v = 1;
  467.       else if (v > NUMCOLORS)
  468.         v = NUMCOLORS;
  469.       BUF(x, y) = v;
  470.     }
  471.       
  472.       subdivide(x1, y1, x, y);
  473.       subdivide(x, y1, x2, y);
  474.       subdivide(x, y, x2, y2);
  475.       subdivide(x1, y, x, y2);
  476.       /* show_pic(buf, global_x, global_y); */
  477.     }
  478. }
  479.  
  480. void Usage(char *prog, char *opt)
  481. {
  482.   fprintf(stderr, "%s:  bad option \"%s\"\n\n", prog, opt);
  483.   fprintf(stderr, "Usage:  %s [options]\n\nWhere options include:\n", prog);
  484.   fprintf(stderr,"    -f <num>\t\t Set global futz factor (default = 2.0)\n");
  485.   fprintf(stderr,"    -dist\t\t Don't make perturbations dependent on dist.\n");
  486.   fprintf(stderr,"    -delay <num>\t Delay in colormap rotation. (default = 1.0).\n");
  487.   fprintf(stderr,"    -display <host:#>\t Specify alternate X server\n");
  488.   fprintf(stderr,"    -s <size>\t\t Use a <size>-square area\n\n");
  489.   exit(1);
  490. }
  491.  
  492. main (int argc, char **argv)
  493. {
  494.   char *display = NULL;
  495.   int x, y, X, Y, i, j;
  496.   int size = 0, testcolor = 0, matrix_size = 4;
  497.   int xsize = 100, ysize = 100;
  498.   
  499.   /* Initialize the random number generator  */
  500.   srand48(getpid());
  501.   
  502.   i = 0;
  503.   
  504.   for(i = 1; i < argc; i++)
  505.     {
  506.       if (! strncmp("-s", argv[i], 2) && i+1 < argc)
  507.     size = atoi(argv[++i]);
  508.       else if (! strncmp("-x", argv[i], 2) && i+1 < argc)
  509.     xsize = atoi(argv[++i]);
  510.       else if (! strncmp("-y", argv[i], 2) && i+1 < argc)
  511.     ysize = atoi(argv[++i]);
  512.       else if (! strncmp("-f", argv[i], 2) && i+1 < argc)
  513.     Futz = atof(argv[++i]);
  514.       else if (! strncmp("-display", argv[i], 8) && i+1 < argc)
  515.     display = argv[++i];
  516.       else if (! strncmp("-delay", argv[i], 6) && i+1 < argc)
  517.     sleep_delay = (int) ((double)sleep_delay * atof(argv[++i]));
  518.       else if (! strncmp("-dist", argv[i], 5))
  519.     usedist = 0;
  520.       else 
  521.         Usage(argv[0], argv[i]);
  522.     }
  523.  
  524.   if (size)
  525.     global_x = global_y = x = y = size;
  526.   else
  527.     {
  528.       global_x = x = xsize;
  529.       global_y = y = ysize;
  530.     }
  531.            
  532.     buf    = (byte *)malloc(x * y);
  533.   if (!buf) 
  534.     {
  535.       fprintf(stderr, "%s: malloc failure.\n", argv[0]);
  536.       exit(1);
  537.     }
  538.   
  539.   memset(buf, 0, x * y);
  540.  
  541.   /*
  542.    *  Prime the 4 corners with random colors.
  543.    */
  544.   BUF(0,0)     = (int)( (drand48() * NUMCOLORS) + 1.0 );
  545.   BUF(x-1,0)   = (int)( (drand48() * NUMCOLORS) + 1.0 );
  546.   BUF(x-1,y-1) = (int)( (drand48() * NUMCOLORS) + 1.0 );
  547.   BUF(0,y-1)   = (int)( (drand48() * NUMCOLORS) + 1.0 );
  548.   fprintf(stderr, "Subdividing ...");  fflush(stderr);
  549.   subdivide(0, 0, x-1, y-1);
  550.   fprintf(stderr, " done\n");  fflush(stderr);
  551.   
  552.   InitX(display, x, y);
  553.   show_pic(buf, x, y);
  554.   manage_window();
  555.   exit(0);
  556. }
  557. @EOF
  558. set `wc -lwc <plasma.c`
  559. if test $1$2$3 != 418135110205
  560. then
  561.     echo ERROR: wc results of plasma.c are $* should be 418 1351 10205
  562. fi
  563.  
  564. chmod 664 plasma.c
  565.  
  566. exit 0
  567. -- 
  568. cheeks@edsr.eds.com    or     ...uunet!edsr!cheeks
  569.