home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / GRAPHICS / ssaver.lzh / SRC / saver_swarm.c < prev    next >
C/C++ Source or Header  |  1995-10-31  |  9KB  |  410 lines

  1. /* saver_swarm.c                                  */
  2. /* A screen-saver program for use with SSaver,    */
  3. /* by Boisy G. Pitre                              */
  4. /* Original swarm.c for XLock,                    */
  5. /* Copyright (c) 1991 by Patrick J. Naughton.     */
  6. /* Compiled by Blair Leduc                        */
  7.  
  8. /* Define if your compiler can inline functions */
  9. #define IN_LINE
  10.  
  11. /* Define if your C preprocessor is smart */
  12. #define SMART_CPP
  13.  
  14. #include <modes.h>
  15. #include <types.h>
  16.  
  17. #include "saver.h"
  18.  
  19. int orgwin, win, twin;
  20.  
  21. int sighandler();    /* this will use a signal handler function */
  22. int sigcode = 0;    /* storage to keep received signal(s) */
  23.  
  24. int gotosleep = FALSE;
  25. unsigned char *scrad=(unsigned char *)0;
  26.  
  27. extern int errno;
  28.  
  29. void drawswarm();
  30. void initswarm();
  31.  
  32. main()
  33. {
  34.     int path, nclrs, i;
  35.     unsigned char pal[768];
  36.     int evID;                    /* event ID */
  37.  
  38.     sigmask(1);                    /* mask signals */
  39.     
  40.     intercept(sighandler);        /* install signal handler */
  41.  
  42.     if ((evID = _ev_link(EV_NAME)) == -1)
  43.         exit(1);
  44.     /* WARNING: if you change the screen type, don't forget to */
  45.     /* change the screen dimensions below */
  46.     DWSet(STDOUT, 7, 0, 0, 96, 60, 15, 0, 0);
  47.     if (_gs_currscr(STDOUT,&orgwin) == -1)
  48.         exit(0);
  49.  
  50.     CurOff(STDOUT);
  51.     BColor(STDOUT, 0);
  52.  
  53.     _gs_wdev(STDOUT, &win);                /* get our window device number */
  54.     _ss_select(STDOUT, win);            /* now select it! */
  55.  
  56.     sigmask(0);                    /* unmask signals */
  57.     _ev_set(evID, 0, 0x8000);    /* wake up everybody */
  58.  
  59.     /* we unlink from the event since we are through with it */
  60.     _ev_unlink(evID);
  61.  
  62.     nclrs=Get_Num_Colors(STDOUT)-2;
  63.     hsbramp(0.0, 1.0, 1.0, 1.0, 1.0, 1.0, nclrs, &pal[3]);
  64.     for(i=1; i<nclrs+1; i++)
  65.         Palette(STDOUT, i, pal[i*3], pal[i*3+1], pal[i*3+2]);
  66.     scrad=(unsigned char *)_gs_scadd(STDOUT);
  67.  
  68.     initswarm(STDOUT);
  69.     
  70.     while(!sigcode)
  71.     {
  72.         if (gotosleep)
  73.             sleep(0);
  74.         else
  75.             /* Do our thing */
  76.             drawswarm(STDOUT);
  77.     }
  78. }
  79.  
  80. sighandler(signal)
  81. int signal;
  82. {
  83.     switch (signal) {
  84.     case SLEEP_SIG:
  85.         gotosleep = TRUE;
  86.         break;
  87.     case WAKE_SIG:
  88.         gotosleep = FALSE;
  89.         break;
  90.     case QUIT_SIG:
  91.     default:
  92.         gotosleep = FALSE;
  93.         sigcode=signal;
  94.         if (_gs_currscr(STDOUT,&twin) == -1)
  95.             exit(0);
  96.         if (twin == win) {
  97.             _ss_select(STDOUT, orgwin);
  98.         }
  99.     }
  100. }
  101.  
  102. /*-
  103.  * swarm.c - swarm of bees for xlock, the X Window System lockscreen.
  104.  *
  105.  * Copyright (c) 1991 by Patrick J. Naughton.
  106.  *
  107.  * Revision History:
  108.  * 26-Oct-95: Ported from xlock suite by Blair Leduc. (b.leduc@ieee.org)
  109.  * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
  110.  */
  111.  
  112. /*
  113.  Permission to use, copy, modify, and distribute this software and its
  114.  documentation for any purpose and without fee is hereby granted,
  115.  provided that the above copyright notice appear in all copies and that
  116.  both that copyright notice and this permission notice appear in
  117.  supporting documentation.
  118.  
  119.  This file is provided AS IS with no warranties of any kind.  The author
  120.  shall have no liability with respect to the infringement of copyrights,
  121.  trade secrets or any patents by this file or any part thereof.  In no
  122.  event will the author be liable for any lost revenue or profits or
  123.  other special, indirect and consequential damages.
  124.  */
  125.  
  126.  
  127. #include <wind.h>
  128.  
  129. unsigned int rand();
  130.  
  131. int sc_width, sc_height;
  132.  
  133. /* if you are running this on a '070, you may want to lower the number */
  134. /* of bees (50 is a bit too much for this machine) */
  135.  
  136. #define TIMES    4        /* number of time positions recorded */
  137. #define BEEACC    3        /* acceleration of bees */
  138. #define WASPACC 5         /* maximum acceleration of wasp */
  139. #define BEEVEL    11        /* maximum bee velocity */
  140. #define WASPVEL 10        /* maximum wasp velocity */
  141. #define BORDER    50        /* wasp won't go closer than this to the edge */
  142. #define NUM_BEES 50     /* number of bees */
  143. #define SC_WIDTH 768
  144. #define SC_WIDTH2 384
  145. #define SC_HEIGHT 480
  146.  
  147. /* Macros */
  148. #define X(t,b)        (sp->x[(t)*sp->beecount+(b)])
  149. #define Y(t,b)        (sp->y[(t)*sp->beecount+(b)])
  150. #define RAND(v)    (rand()%(v)-((v)/2))    /* random number around 0 */
  151. #define SIGN(v) ((v) > 0 ? 1 : ((v) == 0 ? 0 : (-1)))
  152. #define ABS(v)  ((v) >= 0 ? (v) : -(v))
  153.  
  154. typedef struct {
  155.     short x1, y1, x2, y2; /* Defines line segment */
  156. } segments;
  157.  
  158. typedef struct {
  159.     int         pix;
  160.     int         width;
  161.     int         height;
  162.     int            colours;
  163.     int         beecount;    /* number of bees */
  164.     segments   *segs;        /* bee lines */
  165.     segments   *old_segs;    /* old bee lines */
  166.     short      *x;
  167.     short      *y;        /* bee positions x[time][bee#] */
  168.     short      *xv;
  169.     short      *yv;        /* bee velocities xv[bee#] */
  170.     short       wx[3];
  171.     short       wy[3];
  172.     short       wxv;
  173.     short       wyv;
  174. } swarmstruct;
  175.  
  176. static swarmstruct swarm;
  177.  
  178. #ifndef SMART_CPP
  179. #ifdef IN_LINE
  180. inline 
  181. #endif
  182. void drawpoint(x, y, c)
  183. int x,y,c;
  184. {
  185.   unsigned char i, *p;
  186.   
  187.   if (x>=0 && y>=0 && x<SC_WIDTH && y<SC_HEIGHT) {
  188.     p=scrad+y*SC_WIDTH2+(x>>1);
  189.     (*p)&=(x&1)?0xf0:0x0f;
  190.     (*p)|=(x&1)?c:(c<<4);
  191.   }
  192. }
  193. #else
  194. #define drawpoint(x,y,c) \
  195. {\
  196.   unsigned char i, *p;\
  197.   if (x>=0 && y>=0 && x<SC_WIDTH && y<SC_HEIGHT) {\
  198.     p=scrad+y*SC_WIDTH2+(x>>1);\
  199.     (*p)&=(x&1)?0xf0:0x0f;\
  200.     (*p)|=(x&1)?c:(c<<4);\
  201.   }\
  202. }
  203. #endif
  204.  
  205. void initswarm(path)
  206. int path;
  207. {
  208.     swarmstruct *sp=&swarm;
  209.     int         b;
  210.  
  211.         srand(time(0));
  212.         
  213.     sp->beecount = NUM_BEES;
  214.  
  215.     
  216.     /* Get the screen size and number of colours */
  217.  
  218.     sp->colours=Get_Num_Colors(path);
  219.     _gs_scsz(path, &sp->width, &sp->height);
  220.     sp->width*=8;
  221.     sp->height*=8;
  222.  
  223.     
  224.     /* Clear the background. */
  225.  
  226.     BColor(path, 0);
  227.     Clear(path);
  228.  
  229.     
  230.     /* Allocate memory. */
  231.  
  232.     if (!sp->segs) {
  233.         sp->segs = (segments *) malloc(sizeof(segments) * sp->beecount);
  234.         sp->old_segs = (segments *) malloc(sizeof(segments) * sp->beecount);
  235.         sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
  236.         sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
  237.         sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
  238.         sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
  239.     }
  240.  
  241.  
  242.     /* Initialize point positions, velocities, etc. */
  243.  
  244.     /* wasp */
  245.     sp->wx[0] = BORDER + rand() % (sp->width - 2 * BORDER);
  246.     sp->wy[0] = BORDER + rand() % (sp->height - 2 * BORDER);
  247.     sp->wx[1] = sp->wx[0];
  248.     sp->wy[1] = sp->wy[0];
  249.     sp->wxv = 0;
  250.     sp->wyv = 0;
  251.  
  252.     /* bees */
  253.     for (b = 0; b < sp->beecount; b++) {
  254.         X(0, b) = abs(rand()) % sp->width;
  255.         X(1, b) = X(0, b);
  256.         Y(0, b) = abs(rand()) % sp->height;
  257.         Y(1, b) = Y(0, b);
  258.         sp->xv[b] = RAND(7);
  259.         sp->yv[b] = RAND(7);
  260.     }
  261. }
  262.  
  263. void drawline(x1, y1, x2, y2, c)
  264. int x1, y1, x2, y2, c;
  265. {
  266.   int dx, dy, dxabs,dyabs, i, px, py, sdx, sdy, x, y;
  267.   int t;
  268.   
  269.   dx=x2-x1;
  270.   dy=y2-y1;
  271.   sdx=SIGN(dx);
  272.   sdy=SIGN(dy);
  273.   dxabs=ABS(dx);
  274.   dyabs=ABS(dy);
  275.  
  276.   x=0;
  277.   y=0;
  278.   px=x1;
  279.   py=y1;
  280.  
  281.   if (dxabs >= dyabs) {
  282.     for (i=0; i<=dxabs; i++) {
  283.       y+=dyabs;
  284.       if (y>=dxabs) {
  285.         y-=dxabs;
  286.         py+=sdy;
  287.       }
  288.       drawpoint(px,py,c);
  289.       px+=sdx;
  290.     }
  291.   } else {
  292.     for (i=0; i<=dyabs; i++) {
  293.       x+=dxabs;
  294.       if (x>=dyabs) {
  295.         x-=dyabs;
  296.         px+=sdx;
  297.       }
  298.       drawpoint(px,py,c);
  299.       py+=sdy;
  300.     }
  301.   }
  302. }    
  303.  
  304.  
  305. void drawswarm(path)
  306. int path;
  307. {
  308.     swarmstruct *sp=&swarm;
  309.     int b;
  310.  
  311.     /* <=- Wasp -=> */
  312.     /* Age the arrays. */
  313.     sp->wx[2] = sp->wx[1];
  314.     sp->wx[1] = sp->wx[0];
  315.     sp->wy[2] = sp->wy[1];
  316.     sp->wy[1] = sp->wy[0];
  317.     /* Accelerate */
  318.     sp->wxv += RAND(WASPACC);
  319.     sp->wyv += RAND(WASPACC);
  320.  
  321.     /* Speed Limit Checks */
  322.     if (sp->wxv > WASPVEL)
  323.         sp->wxv = WASPVEL;
  324.     if (sp->wxv < -WASPVEL)
  325.         sp->wxv = -WASPVEL;
  326.     if (sp->wyv > WASPVEL)
  327.         sp->wyv = WASPVEL;
  328.     if (sp->wyv < -WASPVEL)
  329.         sp->wyv = -WASPVEL;
  330.  
  331.     /* Move */
  332.     sp->wx[0] = sp->wx[1] + sp->wxv;
  333.     sp->wy[0] = sp->wy[1] + sp->wyv;
  334.  
  335.     /* Bounce Checks */
  336.     if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
  337.         sp->wxv = -sp->wxv;
  338.         sp->wx[0] += sp->wxv;
  339.     }
  340.     if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
  341.         sp->wyv = -sp->wyv;
  342.         sp->wy[0] += sp->wyv;
  343.     }
  344.     /* Don't let things settle down. */
  345.     sp->xv[abs(rand()) % sp->beecount] += RAND(4);
  346.     sp->yv[abs(rand()) % sp->beecount] += RAND(4);
  347.  
  348.     /* <=- Bees -=> */
  349.     for (b = 0; b < sp->beecount; b++) {
  350.         int         distance,
  351.                     dx,
  352.                     dy;
  353.         /* Age the arrays. */
  354.         X(2, b) = X(1, b);
  355.         X(1, b) = X(0, b);
  356.         Y(2, b) = Y(1, b);
  357.         Y(1, b) = Y(0, b);
  358.  
  359.         /* Accelerate */
  360.         dx = sp->wx[1] - X(1, b);
  361.         dy = sp->wy[1] - Y(1, b);
  362.         distance = abs(dx) + abs(dy);    /* approximation */
  363.         if (distance == 0)
  364.             distance = 1;
  365.         sp->xv[b] += (dx * BEEACC) / distance;
  366.         sp->yv[b] += (dy * BEEACC) / distance;
  367.  
  368.         /* Speed Limit Checks */
  369.         if (sp->xv[b] > BEEVEL)
  370.             sp->xv[b] = BEEVEL;
  371.         if (sp->xv[b] < -BEEVEL)
  372.             sp->xv[b] = -BEEVEL;
  373.         if (sp->yv[b] > BEEVEL)
  374.             sp->yv[b] = BEEVEL;
  375.         if (sp->yv[b] < -BEEVEL)
  376.             sp->yv[b] = -BEEVEL;
  377.  
  378.         /* Move */
  379.         X(0, b) = X(1, b) + sp->xv[b];
  380.         Y(0, b) = Y(1, b) + sp->yv[b];
  381.  
  382.         /* Fill the segment lists. */
  383.         sp->segs[b].x1 = X(0, b);
  384.         sp->segs[b].y1 = Y(0, b);
  385.         sp->segs[b].x2 = X(1, b);
  386.         sp->segs[b].y2 = Y(1, b);
  387.         sp->old_segs[b].x1 = X(1, b);
  388.         sp->old_segs[b].y1 = Y(1, b);
  389.         sp->old_segs[b].x2 = X(2, b);
  390.         sp->old_segs[b].y2 = Y(2, b);
  391.     }
  392.  
  393.     drawline(sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2], 0);
  394.  
  395.     for (b=0; b<sp->beecount; b++) {
  396.         drawline(sp->old_segs[b].x1, sp->old_segs[b].y1,
  397.                          sp->old_segs[b].x2, sp->old_segs[b].y2, 0);
  398.     }
  399.  
  400.     drawline(sp->wx[0], sp->wy[0],sp->wx[1], sp->wy[1], sp->colours-1);
  401.  
  402.     if (++sp->pix >= sp->colours-1)
  403.         sp->pix = 1;
  404.  
  405.     for (b=0; b<sp->beecount; b++) {
  406.         drawline(sp->segs[b].x1, sp->segs[b].y1,
  407.                  sp->segs[b].x2, sp->segs[b].y2, sp->pix);
  408.     }
  409. }
  410.