home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xlock / rotor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  6.0 KB  |  250 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)rotor.c    1.6 91/05/24 XLOCK";
  3. #endif
  4. /*-
  5.  * rotor.c - A swirly rotor for xlock, the X Window System lockscreen.
  6.  *
  7.  * Copyright (c) 1991 by Patrick J. Naughton.
  8.  *
  9.  * See xlock.c for copying information.
  10.  *
  11.  * Revision History:
  12.  * 11-Nov-90: put into xlock (by Steve Zellers, zellers@sun.com)
  13.  * 16-Oct-90: Received from Tom Lawrence (tcl@cs.brown.edu: 'flight' simulator)
  14.  */
  15.  
  16. /*
  17.  * A 'batchcount' of 3 or 4 works best!
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <math.h>
  22. #include "xlock.h"
  23.  
  24. #define SAVE         100    /* this is a good constant to tweak */
  25. #define REPS          50
  26.  
  27. #define MAXANGLE    10000.0    /* irrectangular */
  28. #define DEFAULTCOUNT    3
  29.  
  30. typedef unsigned char Boolean;
  31.  
  32. #define IDENT(X)    X
  33. #ifdef __STDC__
  34. #define CAT(X,Y)    X##Y
  35. #else
  36. #define CAT(X,Y)    IDENT(X)Y
  37. #endif
  38.  
  39. struct elem {
  40.     float       angle;
  41.     float       radius;
  42.     float       start_radius;
  43.     float       end_radius;
  44.     float       radius_drift_max;
  45.     float       radius_drift_now;
  46.  
  47.     float       ratio;
  48.     float       start_ratio;
  49.     float       end_ratio;
  50.     float       ratio_drift_max;
  51.     float       ratio_drift_now;
  52. };
  53.  
  54. typedef struct flightstruct {
  55.     struct elem *elements;
  56.     int         pix;
  57.     int         lastx,
  58.                 lasty;
  59.     int         num,
  60.                 rotor,
  61.                 prev;
  62.     int         savex[SAVE],
  63.                 savey[SAVE];
  64.     float       angle;
  65.     int         centerx,
  66.                 centery;
  67.     Boolean     firsttime;
  68.     Boolean     smallscreen;    /* for iconified view */
  69.     Boolean     forward;
  70.     Boolean     unused;
  71. }           flightstruct;
  72.  
  73.  
  74. static flightstruct flights[MAXSCREENS];
  75.  
  76. void
  77. initrotor(win)
  78.     Window      win;
  79. {
  80.     flightstruct *fs = &flights[screen];
  81.     XWindowAttributes xgwa;
  82.     int         x;
  83.     struct elem *pelem;
  84.     Boolean     wassmall;
  85.  
  86.     XGetWindowAttributes(dsp, win, &xgwa);
  87.     fs->centerx = xgwa.width / 2;
  88.     fs->centery = xgwa.height / 2;
  89.  
  90.     /*
  91.      * sometimes, you go into small view, only to see a really whizzy pattern
  92.      * that you would like to look more closely at. Normally, clicking in the
  93.      * icon reinitializes everything - but I don't, cuz I'm that kind of guy.
  94.      * HENCE, the wassmall stuff you see here.
  95.      */
  96.  
  97.     wassmall = fs->smallscreen;
  98.     fs->smallscreen = (xgwa.width < 100);
  99.  
  100.     if (wassmall && !fs->smallscreen)
  101.     fs->firsttime = True;
  102.     else {
  103.     if (batchcount > 12)
  104.         batchcount = DEFAULTCOUNT;
  105.     fs->num = batchcount;
  106.  
  107.     if (fs->elements == NULL) {
  108.         if ((fs->elements = (struct elem *)
  109.         malloc(sizeof(struct elem) * fs->num)) == 0) {
  110.         perror("malloc");
  111.         exit(1);
  112.         }
  113.     }
  114.     memset(fs->savex, 0, sizeof(fs->savex));
  115.  
  116.     pelem = fs->elements;
  117.  
  118.     for (x = fs->num; --x >= 0; pelem++) {
  119.         pelem->radius_drift_max = 1.0;
  120.         pelem->radius_drift_now = 1.0;
  121.  
  122.         pelem->end_radius = 100.0;
  123.  
  124.         pelem->ratio_drift_max = 1.0;
  125.         pelem->ratio_drift_now = 1.0;
  126.         pelem->end_ratio = 10.0;
  127.     }
  128.  
  129.     fs->rotor = 0;
  130.     fs->prev = 1;
  131.     fs->lastx = fs->centerx;
  132.     fs->lasty = fs->centery;
  133.     fs->angle = (random() % (long) MAXANGLE) / 3;
  134.     fs->forward = fs->firsttime = True;
  135.     }
  136.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  137.     XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, xgwa.width, xgwa.height);
  138. }
  139.  
  140. void
  141. drawrotor(win)
  142.     Window      win;
  143. {
  144.     register flightstruct *fs = &flights[screen];
  145.     register struct elem *pelem;
  146.     int         thisx,
  147.                 thisy;
  148.     int         i,
  149.                 rp;
  150.     int         x1,
  151.                 y1,
  152.                 x2,
  153.                 y2;
  154.  
  155.  
  156. #define SCALE(W,N)    CAT(W,N)/=12; CAT(W,N)+=(CAT(fs->center,W)-2)
  157. #define SCALEIFSMALL()    if (fs->smallscreen) {     \
  158.                               SCALE(x,1); SCALE(x,2);    \
  159.                   SCALE(y,1); SCALE(y,2);    \
  160.               }
  161.  
  162.     for (rp = 0; rp < REPS; rp++) {
  163.     thisx = fs->centerx;
  164.     thisy = fs->centery;
  165.  
  166.     for (i = fs->num, pelem = fs->elements; --i >= 0; pelem++) {
  167.         if (pelem->radius_drift_max <= pelem->radius_drift_now) {
  168.         pelem->start_radius = pelem->end_radius;
  169.         pelem->end_radius =
  170.             (float) (random() % 40000) / 100.0 - 200.0;
  171.         pelem->radius_drift_max =
  172.             (float) (random() % 100000) + 10000.0;
  173.         pelem->radius_drift_now = 0.0;
  174.         }
  175.         if (pelem->ratio_drift_max <= pelem->ratio_drift_now) {
  176.         pelem->start_ratio = pelem->end_ratio;
  177.         pelem->end_ratio =
  178.             (float) (random() % 2000) / 100.0 - 10.0;
  179.         pelem->ratio_drift_max =
  180.             (float) (random() % 100000) + 10000.0;
  181.         pelem->ratio_drift_now = 0.0;
  182.         }
  183.         pelem->ratio = pelem->start_ratio +
  184.         (pelem->end_ratio - pelem->start_ratio) /
  185.         pelem->ratio_drift_max * pelem->ratio_drift_now;
  186.         pelem->angle = fs->angle * pelem->ratio;
  187.         pelem->radius = pelem->start_radius +
  188.         (pelem->end_radius - pelem->start_radius) /
  189.         pelem->radius_drift_max * pelem->radius_drift_now;
  190.  
  191.         thisx += (int) (cos(pelem->angle) * pelem->radius);
  192.         thisy += (int) (sin(pelem->angle) * pelem->radius);
  193.  
  194.         pelem->ratio_drift_now += 1.0;
  195.         pelem->radius_drift_now += 1.0;
  196.     }
  197.     if (fs->firsttime)
  198.         fs->firsttime = False;
  199.     else {
  200.         XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  201.  
  202.         x1 = (int) fs->savex[fs->rotor];
  203.         y1 = (int) fs->savey[fs->rotor];
  204.         x2 = (int) fs->savex[fs->prev];
  205.         y2 = (int) fs->savey[fs->prev];
  206.  
  207.         SCALEIFSMALL();
  208.  
  209.         XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2);
  210.  
  211.         if (!mono && Scr[screen].npixels > 2) {
  212.         XSetForeground(dsp, Scr[screen].gc,
  213.                    Scr[screen].pixels[fs->pix]);
  214.         if (++fs->pix >= Scr[screen].npixels)
  215.             fs->pix = 0;
  216.         } else
  217.         XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen));
  218.  
  219.         x1 = fs->lastx;
  220.         y1 = fs->lasty;
  221.         x2 = thisx;
  222.         y2 = thisy;
  223.  
  224.         SCALEIFSMALL();
  225.  
  226.         XDrawLine(dsp, win, Scr[screen].gc, x1, y1, x2, y2);
  227.     }
  228.     fs->savex[fs->rotor] = fs->lastx = thisx;
  229.     fs->savey[fs->rotor] = fs->lasty = thisy;
  230.  
  231.     ++fs->rotor;
  232.     fs->rotor %= SAVE;
  233.     ++fs->prev;
  234.     fs->prev %= SAVE;
  235.     if (fs->forward) {
  236.         fs->angle += 0.01;
  237.         if (fs->angle >= MAXANGLE) {
  238.         fs->angle = MAXANGLE;
  239.         fs->forward = False;
  240.         }
  241.     } else {
  242.         fs->angle -= 0.1;
  243.         if (fs->angle <= 0) {
  244.         fs->angle = 0.0;
  245.         fs->forward = True;
  246.         }
  247.     }
  248.     }
  249. }
  250.