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 >
Wrap
C/C++ Source or Header
|
1995-10-31
|
9KB
|
410 lines
/* saver_swarm.c */
/* A screen-saver program for use with SSaver, */
/* by Boisy G. Pitre */
/* Original swarm.c for XLock, */
/* Copyright (c) 1991 by Patrick J. Naughton. */
/* Compiled by Blair Leduc */
/* Define if your compiler can inline functions */
#define IN_LINE
/* Define if your C preprocessor is smart */
#define SMART_CPP
#include <modes.h>
#include <types.h>
#include "saver.h"
int orgwin, win, twin;
int sighandler(); /* this will use a signal handler function */
int sigcode = 0; /* storage to keep received signal(s) */
int gotosleep = FALSE;
unsigned char *scrad=(unsigned char *)0;
extern int errno;
void drawswarm();
void initswarm();
main()
{
int path, nclrs, i;
unsigned char pal[768];
int evID; /* event ID */
sigmask(1); /* mask signals */
intercept(sighandler); /* install signal handler */
if ((evID = _ev_link(EV_NAME)) == -1)
exit(1);
/* WARNING: if you change the screen type, don't forget to */
/* change the screen dimensions below */
DWSet(STDOUT, 7, 0, 0, 96, 60, 15, 0, 0);
if (_gs_currscr(STDOUT,&orgwin) == -1)
exit(0);
CurOff(STDOUT);
BColor(STDOUT, 0);
_gs_wdev(STDOUT, &win); /* get our window device number */
_ss_select(STDOUT, win); /* now select it! */
sigmask(0); /* unmask signals */
_ev_set(evID, 0, 0x8000); /* wake up everybody */
/* we unlink from the event since we are through with it */
_ev_unlink(evID);
nclrs=Get_Num_Colors(STDOUT)-2;
hsbramp(0.0, 1.0, 1.0, 1.0, 1.0, 1.0, nclrs, &pal[3]);
for(i=1; i<nclrs+1; i++)
Palette(STDOUT, i, pal[i*3], pal[i*3+1], pal[i*3+2]);
scrad=(unsigned char *)_gs_scadd(STDOUT);
initswarm(STDOUT);
while(!sigcode)
{
if (gotosleep)
sleep(0);
else
/* Do our thing */
drawswarm(STDOUT);
}
}
sighandler(signal)
int signal;
{
switch (signal) {
case SLEEP_SIG:
gotosleep = TRUE;
break;
case WAKE_SIG:
gotosleep = FALSE;
break;
case QUIT_SIG:
default:
gotosleep = FALSE;
sigcode=signal;
if (_gs_currscr(STDOUT,&twin) == -1)
exit(0);
if (twin == win) {
_ss_select(STDOUT, orgwin);
}
}
}
/*-
* swarm.c - swarm of bees for xlock, the X Window System lockscreen.
*
* Copyright (c) 1991 by Patrick J. Naughton.
*
* Revision History:
* 26-Oct-95: Ported from xlock suite by Blair Leduc. (b.leduc@ieee.org)
* 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
*/
/*
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.
This file is provided AS IS with no warranties of any kind. The author
shall have no liability with respect to the infringement of copyrights,
trade secrets or any patents by this file or any part thereof. In no
event will the author be liable for any lost revenue or profits or
other special, indirect and consequential damages.
*/
#include <wind.h>
unsigned int rand();
int sc_width, sc_height;
/* if you are running this on a '070, you may want to lower the number */
/* of bees (50 is a bit too much for this machine) */
#define TIMES 4 /* number of time positions recorded */
#define BEEACC 3 /* acceleration of bees */
#define WASPACC 5 /* maximum acceleration of wasp */
#define BEEVEL 11 /* maximum bee velocity */
#define WASPVEL 10 /* maximum wasp velocity */
#define BORDER 50 /* wasp won't go closer than this to the edge */
#define NUM_BEES 50 /* number of bees */
#define SC_WIDTH 768
#define SC_WIDTH2 384
#define SC_HEIGHT 480
/* Macros */
#define X(t,b) (sp->x[(t)*sp->beecount+(b)])
#define Y(t,b) (sp->y[(t)*sp->beecount+(b)])
#define RAND(v) (rand()%(v)-((v)/2)) /* random number around 0 */
#define SIGN(v) ((v) > 0 ? 1 : ((v) == 0 ? 0 : (-1)))
#define ABS(v) ((v) >= 0 ? (v) : -(v))
typedef struct {
short x1, y1, x2, y2; /* Defines line segment */
} segments;
typedef struct {
int pix;
int width;
int height;
int colours;
int beecount; /* number of bees */
segments *segs; /* bee lines */
segments *old_segs; /* old bee lines */
short *x;
short *y; /* bee positions x[time][bee#] */
short *xv;
short *yv; /* bee velocities xv[bee#] */
short wx[3];
short wy[3];
short wxv;
short wyv;
} swarmstruct;
static swarmstruct swarm;
#ifndef SMART_CPP
#ifdef IN_LINE
inline
#endif
void drawpoint(x, y, c)
int x,y,c;
{
unsigned char i, *p;
if (x>=0 && y>=0 && x<SC_WIDTH && y<SC_HEIGHT) {
p=scrad+y*SC_WIDTH2+(x>>1);
(*p)&=(x&1)?0xf0:0x0f;
(*p)|=(x&1)?c:(c<<4);
}
}
#else
#define drawpoint(x,y,c) \
{\
unsigned char i, *p;\
if (x>=0 && y>=0 && x<SC_WIDTH && y<SC_HEIGHT) {\
p=scrad+y*SC_WIDTH2+(x>>1);\
(*p)&=(x&1)?0xf0:0x0f;\
(*p)|=(x&1)?c:(c<<4);\
}\
}
#endif
void initswarm(path)
int path;
{
swarmstruct *sp=&swarm;
int b;
srand(time(0));
sp->beecount = NUM_BEES;
/* Get the screen size and number of colours */
sp->colours=Get_Num_Colors(path);
_gs_scsz(path, &sp->width, &sp->height);
sp->width*=8;
sp->height*=8;
/* Clear the background. */
BColor(path, 0);
Clear(path);
/* Allocate memory. */
if (!sp->segs) {
sp->segs = (segments *) malloc(sizeof(segments) * sp->beecount);
sp->old_segs = (segments *) malloc(sizeof(segments) * sp->beecount);
sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
}
/* Initialize point positions, velocities, etc. */
/* wasp */
sp->wx[0] = BORDER + rand() % (sp->width - 2 * BORDER);
sp->wy[0] = BORDER + rand() % (sp->height - 2 * BORDER);
sp->wx[1] = sp->wx[0];
sp->wy[1] = sp->wy[0];
sp->wxv = 0;
sp->wyv = 0;
/* bees */
for (b = 0; b < sp->beecount; b++) {
X(0, b) = abs(rand()) % sp->width;
X(1, b) = X(0, b);
Y(0, b) = abs(rand()) % sp->height;
Y(1, b) = Y(0, b);
sp->xv[b] = RAND(7);
sp->yv[b] = RAND(7);
}
}
void drawline(x1, y1, x2, y2, c)
int x1, y1, x2, y2, c;
{
int dx, dy, dxabs,dyabs, i, px, py, sdx, sdy, x, y;
int t;
dx=x2-x1;
dy=y2-y1;
sdx=SIGN(dx);
sdy=SIGN(dy);
dxabs=ABS(dx);
dyabs=ABS(dy);
x=0;
y=0;
px=x1;
py=y1;
if (dxabs >= dyabs) {
for (i=0; i<=dxabs; i++) {
y+=dyabs;
if (y>=dxabs) {
y-=dxabs;
py+=sdy;
}
drawpoint(px,py,c);
px+=sdx;
}
} else {
for (i=0; i<=dyabs; i++) {
x+=dxabs;
if (x>=dyabs) {
x-=dyabs;
px+=sdx;
}
drawpoint(px,py,c);
py+=sdy;
}
}
}
void drawswarm(path)
int path;
{
swarmstruct *sp=&swarm;
int b;
/* <=- Wasp -=> */
/* Age the arrays. */
sp->wx[2] = sp->wx[1];
sp->wx[1] = sp->wx[0];
sp->wy[2] = sp->wy[1];
sp->wy[1] = sp->wy[0];
/* Accelerate */
sp->wxv += RAND(WASPACC);
sp->wyv += RAND(WASPACC);
/* Speed Limit Checks */
if (sp->wxv > WASPVEL)
sp->wxv = WASPVEL;
if (sp->wxv < -WASPVEL)
sp->wxv = -WASPVEL;
if (sp->wyv > WASPVEL)
sp->wyv = WASPVEL;
if (sp->wyv < -WASPVEL)
sp->wyv = -WASPVEL;
/* Move */
sp->wx[0] = sp->wx[1] + sp->wxv;
sp->wy[0] = sp->wy[1] + sp->wyv;
/* Bounce Checks */
if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
sp->wxv = -sp->wxv;
sp->wx[0] += sp->wxv;
}
if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
sp->wyv = -sp->wyv;
sp->wy[0] += sp->wyv;
}
/* Don't let things settle down. */
sp->xv[abs(rand()) % sp->beecount] += RAND(4);
sp->yv[abs(rand()) % sp->beecount] += RAND(4);
/* <=- Bees -=> */
for (b = 0; b < sp->beecount; b++) {
int distance,
dx,
dy;
/* Age the arrays. */
X(2, b) = X(1, b);
X(1, b) = X(0, b);
Y(2, b) = Y(1, b);
Y(1, b) = Y(0, b);
/* Accelerate */
dx = sp->wx[1] - X(1, b);
dy = sp->wy[1] - Y(1, b);
distance = abs(dx) + abs(dy); /* approximation */
if (distance == 0)
distance = 1;
sp->xv[b] += (dx * BEEACC) / distance;
sp->yv[b] += (dy * BEEACC) / distance;
/* Speed Limit Checks */
if (sp->xv[b] > BEEVEL)
sp->xv[b] = BEEVEL;
if (sp->xv[b] < -BEEVEL)
sp->xv[b] = -BEEVEL;
if (sp->yv[b] > BEEVEL)
sp->yv[b] = BEEVEL;
if (sp->yv[b] < -BEEVEL)
sp->yv[b] = -BEEVEL;
/* Move */
X(0, b) = X(1, b) + sp->xv[b];
Y(0, b) = Y(1, b) + sp->yv[b];
/* Fill the segment lists. */
sp->segs[b].x1 = X(0, b);
sp->segs[b].y1 = Y(0, b);
sp->segs[b].x2 = X(1, b);
sp->segs[b].y2 = Y(1, b);
sp->old_segs[b].x1 = X(1, b);
sp->old_segs[b].y1 = Y(1, b);
sp->old_segs[b].x2 = X(2, b);
sp->old_segs[b].y2 = Y(2, b);
}
drawline(sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2], 0);
for (b=0; b<sp->beecount; b++) {
drawline(sp->old_segs[b].x1, sp->old_segs[b].y1,
sp->old_segs[b].x2, sp->old_segs[b].y2, 0);
}
drawline(sp->wx[0], sp->wy[0],sp->wx[1], sp->wy[1], sp->colours-1);
if (++sp->pix >= sp->colours-1)
sp->pix = 1;
for (b=0; b<sp->beecount; b++) {
drawline(sp->segs[b].x1, sp->segs[b].y1,
sp->segs[b].x2, sp->segs[b].y2, sp->pix);
}
}