1 /* t3d -- Flying Balls Clock Demo
2 by Bernd Paysan , paysan@informatik.tu-muenchen.de
4 Copy, modify, and distribute T3D either under GPL version 2 or newer,
5 or under the standard MIT/X license notice.
7 partly based on flying balls demo by Georg Acher,
8 acher@informatik.tu-muenchen.de
9 (developed on HP9000/720 (55 MIPS,20 MFLOPS) )
10 NO warranty at all ! Complaints to /dev/null !
12 4-Jan-99 jwz@jwz.org -- adapted to xscreensaver framework, to take advantage
13 of the command-line options provided by screenhack.c.
19 #endif /* !HAVE_COCOA */
23 #include <time.h> /* for localtime() and gettimeofday() */
25 #include "screenhack.h"
36 #define MIN(i,j) ((i)<(j)?(i):(j))
38 #define kmax ((st->minutes?60:24))
39 /* Anzahl der Kugeln */
41 /* Werte in der Sinus-Tabelle */
42 /*-----------------------------------------------------------------*/
43 #define setink(inkcolor) \
44 XSetForeground (st->dpy,st->gc,inkcolor)
46 #define drawline(xx1,yy1,xx2,yy2) \
47 XDrawLine(st->dpy,st->win,st->gc,xx1,yy1,xx2,yy2)
49 #define drawseg(segments,nr_segments) \
50 XDrawSegments(st->dpy,st->win,st->gc,segments,nr_segments)
53 #define polyfill(ppts,pcount) \
54 XFillPolygon(st->dpy,st->win,st->gc,ppts,pcount,Convex,CoordModeOrigin)
57 #define frac(argument) argument-floor(argument)
60 #define ABS(x) ((x)<0.0 ? -(x) : (x))
83 double a[3],am[3],x[3],y[3],v[3];
84 double zoom,speed,zaehler,vspeed;
87 double cosinus[sines];
94 double movef, wobber, cycle;
96 XWindowAttributes xgwa;
100 int scrnWidth, scrnHeight;
110 Window junk_win,in_win;
119 # define sum1ton(a) (((a)*(a)+1)/2)
120 # define fastcw sum1ton(st->fastch)
123 # else /* !FASTCOPY */
124 XImage* fastcircles[maxfast];
125 XImage* fastmask[maxfast];
126 # endif /* !FASTCOPY */
127 # endif /* FASTDRAW */
137 gettime (struct state *st)
139 struct timeval time1;
143 #ifdef GETTIMEOFDAY_TWO_ARGS
144 struct timezone zone1;
145 gettimeofday(&time1,&zone1);
147 gettimeofday(&time1);
149 lt = time1.tv_sec; /* avoid type cast lossage */
152 return (zeit->tm_sec+60*(zeit->tm_min+60*(zeit->tm_hour))
153 + time1.tv_usec*1.0E-6);
156 /* --------------------COLORMAP---------------------*/
159 hsv2rgb (double h, double s, double v, double *r, double *g, double *b)
161 h/=360.0; h=6*(h-floor(h));
179 case 0: *r=v; *g=t; *b=w; break;
180 case 1: *r=u; *g=v; *b=w; break;
181 case 2: *r=w; *g=v; *b=t; break;
182 case 3: *r=w; *g=u; *b=v; break;
183 case 4: *r=t; *g=w; *b=v; break;
184 case 5: *r=v; *g=w; *b=u; break;
188 printf("HSV: %f %f %f to\nRGB: %f %f %f\n",h,s,v,*r,*g,*b);
193 changeColor (struct state *st, double r, double g, double b)
200 st->colors[n1].red =1023+ n*(int)(1024.*r);
201 st->colors[n1].blue =1023+ n*(int)(1024.*b);
202 st->colors[n1].green =1023+ n*(int)(1024.*g);
207 XStoreColors (st->dpy, st->cmap, st->colors, 12);
211 initColor (struct state *st, double r, double g, double b)
214 unsigned long pixels[12];
217 st->cmap = st->xgwa.colormap;
219 if(st->hsvcycl!=0.0 && XAllocColorCells(st->dpy, st->cmap, 0, &dummy, 0, pixels, 12))
223 st->colors[n1].pixel=pixels[n1];
224 st->colors[n1].flags=DoRed | DoGreen | DoBlue;
227 changeColor(st,r,g,b);
234 st->colors[n1].red =1023+ n*(int)(1024.*r);
235 st->colors[n1].blue =1023+ n*(int)(1024.*b);
236 st->colors[n1].green =1023+ n*(int)(1024.*g);
238 if (!(XAllocColor (st->dpy, st->cmap, &st->colors[n1]))) {
239 fprintf (stderr, "Error: Cannot allocate colors\n");
248 /* ----------------WINDOW-------------------*/
251 initialize (struct state *st)
258 st->r = st->g = st->b = 1;
259 st->hue = st->sat = 0;
265 st->scrnWidth = WIDTH;
266 st->scrnHeight = HEIGHT;
269 XGetWindowAttributes (st->dpy, st->window, &st->xgwa);
270 st->scrnWidth = st->xgwa.width;
271 st->scrnHeight = st->xgwa.height;
274 float f = get_float_resource (st->dpy, "cycle", "Float");
275 if (f <= 0 || f > 60) f = 6.0;
276 st->cycle = 60.0 / f;
278 st->movef = get_float_resource (st->dpy, "move", "Float");
279 st->wobber = get_float_resource (st->dpy, "wobble", "Float");
282 double magfac = get_float_resource (st->dpy, "mag", "Float");
284 st->fastch=(int)(st->fastch*magfac);
287 if (get_boolean_resource (st->dpy, "minutes", "Boolean")) {
288 st->minutes=1; st->maxk+=60-24;
291 st->timewait = get_integer_resource (st->dpy, "delay", "Integer");
292 st->fastch = get_integer_resource (st->dpy, "fast", "Integer");
293 st->cycl = get_boolean_resource (st->dpy, "colcycle", "Integer");
294 st->hsvcycl = get_float_resource (st->dpy, "hsvcycle", "Integer");
297 char *s = get_string_resource (st->dpy, "rgb", "RGB");
302 if (3 == sscanf (s, "%lf %lf %lf %c", &rr, &gg, &bb, &dummy))
303 st->r = rr, st->g = gg, st->b = bb;
307 s = get_string_resource (st->dpy, "hsv", "HSV");
311 if (3 == sscanf (s, "%lf %lf %lf %c", &hh, &ss, &vv, &dummy)) {
312 st->hue = hh, st->sat = ss, st->val = vv;
313 hsv2rgb(st->hue,st->sat,st->val,&st->r,&st->g,&st->b);
319 if (st->fastch > maxfast)
322 xgc=( XGCValues *) malloc(sizeof(XGCValues) );
323 xorgc=( XGCValues *) malloc(sizeof(XGCValues) );
324 xandgc=( XGCValues *) malloc(sizeof(XGCValues) );
326 st->planes=st->xgwa.depth;
329 # define GXandInverted GXcopy /* #### this can't be right, right? */
331 st->gc = XCreateGC (st->dpy, st->window, 0, xgc);
332 xorgc->function =GXor;
333 st->orgc = XCreateGC (st->dpy, st->window, GCFunction, xorgc);
334 xandgc->function =GXandInverted;
335 st->andgc = XCreateGC (st->dpy, st->window, GCFunction, xandgc);
337 st->buffer = XCreatePixmap (st->dpy, st->window, st->scrnWidth, st->scrnHeight,
341 printf("Time 3D drawing ");
344 puts("fast by Pixmap copy");
346 puts("fast by XImage copy");
354 st->fastcircles = XCreatePixmap (st->dpy, st->window, fastcw, st->fastch+1, st->xgwa.depth);
355 st->fastmask = XCreatePixmap (st->dpy, st->window, fastcw, st->fastch+1, st->xgwa.depth);
358 setink(BlackPixelOfScreen (st->xgwa.screen));
359 XFillRectangle (st->dpy, st->buffer , st->gc, 0, 0, st->scrnWidth, st->scrnHeight);
364 XFillRectangle (st->dpy, st->fastcircles, st->gc, 0, 0, fastcw, st->fastch+1);
365 XFillRectangle (st->dpy, st->fastmask , st->gc, 0, 0, fastcw, st->fastch+1);
370 printf("move\t%.2f\nwobber\t%.2f\nmag\t%.2f\ncycle\t%.4f\n",
371 st->movef,st->wobber,st->mag/10,st->cycle);
372 printf("fast\t%i\nmarks\t%i\nwait\t%i\n",st->fastch,st->maxk,st->timewait);
377 static void fill_kugel(struct state *st, int i, Pixmap buf, int setcol);
380 /*------------------------------------------------------------------*/
382 init_kugel(struct state *st)
388 for(i=0; i<st->fastch; i++)
391 st->kugeln[i].r1=-((double) i)/2 -1;
392 st->kugeln[i].x1=sum1ton(i);
393 st->kugeln[i].y1=((double) i)/2 +1;
395 fill_kugel(st,i,st->fastcircles,1);
396 setink((1<<MIN(24,st->xgwa.depth))-1);
397 fill_kugel(st,i,st->fastmask,0);
399 st->kugeln[i].r1=-((double) i)/2 -1;
400 st->kugeln[i].x1=st->kugeln[i].y1=((double) i)/2 +1;
402 fill_kugel(i,st->buffer,1);
403 st->fastcircles[i]=XGetImage(st->dpy,st->buffer,0,0,i+2,i+2,(1<<st->planes)-1,ZPixmap);
405 setink((1<<MIN(24,st->xgwa.depth))-1);
406 fill_kugel(i,st->buffer,0);
407 st->fastmask[i]=XGetImage(st->dpy,st->buffer,0,0,i+2,i+2,(1<<st->planes)-1,ZPixmap);
410 XFillRectangle (st->dpy, st->buffer , st->gc, 0, 0, st->scrnWidth, st->scrnHeight);
417 /* Zeiger zeichnen */
420 zeiger(struct state *st, double dist,double rad, double z, double sec, int *q)
423 double gratio=sqrt(2.0/(1.0+sqrt(5.0)));
429 st->kugeln[n].x=dist*cos(sec);
430 st->kugeln[n].y=-dist*sin(sec);
441 /*-----------------------------------------------------------------*
443 *-----------------------------------------------------------------*/
446 manipulate(struct state *st, double k)
448 double i,l,/*xs,*/ys,zs,mod;
449 double /*persec,*/sec,min,hour;
452 sec=TWOPI*modf(k/60,&mod);
453 min=TWOPI*modf(k/3600,&mod);
454 hour=TWOPI*modf(k/43200,&mod);
456 l=TWOPI*modf(k/300,&mod);
461 st->kugeln[n].x=4.0*sin(i);
462 st->kugeln[n].y=4.0*cos(i);
463 st->kugeln[n].z=st->wobber* /* (sin(floor(2+2*l/(PI))*i)*sin(2*l)); */
464 cos((i-sec)*floor(2+5*l/(PI)))*sin(5*l);
467 st->kugeln[n].r=/* (1.0+0.3*cos(floor(2+2*l/(PI))*i)*sin(2*l))* */
468 ((n % 5!=0) ? 0.3 : 0.6)*
469 ((n % 15 ==0) ? 1.25 : .75);
473 st->kugeln[n].r=/* (1.0+0.3*cos(floor(2+2*l/(PI))*i)*sin(2*l))* */
474 ((n & 1) ? 0.5 : 1.0)*
475 ((n % 6==0) ? 1.25 : .75);
483 st->kugeln[n].r=2.0+cos(TWOPI*modf(k,&mod))/2;
486 zeiger(st,2.0,0.75,-2.0,sec,&n);
487 zeiger(st,1.0,1.0,-1.5,min,&n);
488 zeiger(st,0.0,1.5,-1.0,hour,&n);
490 for(n=0;n<st->maxk;n++)
492 ys=st->kugeln[n].y*cos(st->movef*sin(st->cycle*sec))+
493 st->kugeln[n].z*sin(st->movef*sin(st->cycle*sec));
494 zs=-st->kugeln[n].y*sin(st->movef*sin(st->cycle*sec))+
495 st->kugeln[n].z*cos(st->movef*sin(st->cycle*sec));
500 /*------------------------------------------------------------------*/
502 t3d_sort(struct state *st, int l, int r)
509 x=st->kugeln[(l+r)/2].d;
512 while(st->kugeln[i].d>x) i++;
513 while(x>st->kugeln[j].d) j--;
516 ex=st->kugeln[i];st->kugeln[i]=st->kugeln[j];st->kugeln[j]=ex;
521 if (l<j) t3d_sort(st,l,j);
522 if (i<r) t3d_sort(st,i,r);
525 /*------------------------------------------------------------------*/
527 fill_kugel(struct state *st, int i, Pixmap buf, int setcol)
530 int m,col,inc=1,inr=3,d;
531 d=(int)((ABS(st->kugeln[i].r1)*2));
535 if(st->fastdraw && d<st->fastch)
538 XCopyArea(st->dpy, st->fastmask, buf, st->andgc, sum1ton(d)-(d+1)/2, 1,d,d,
539 (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2);
540 XCopyArea(st->dpy, st->fastcircles, buf, st->orgc, sum1ton(d)-(d+1)/2, 1,d,d,
541 (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2);
543 XPutImage(st->dpy, buf, st->andgc, st->fastmask[d-1], 0, 0,
544 (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2, d, d);
545 XPutImage(st->dpy, buf, st->orgc, st->fastcircles[d-1], 0, 0,
546 (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2, d, d);
552 if(ABS(st->kugeln[i].r1)<6.0) inr=9;
554 for (m=0;m<=28;m+=inr)
556 ra=st->kugeln[i].r1*sqrt(1-m*m/(28.0*28.0));
558 printf("Radius: %f\n",ra);
561 else if(-ra< 6.0) inc=8;
562 else if(-ra<20.0) inc=4;
563 else if(-ra<40.0) inc=2;
569 if (col>33) col=33; col/=3;
570 setink(st->colors[col].pixel);
576 for (n=0,nr=0;n<=sines-1;n+=inc,nr++)
578 track[nr].x=st->kugeln[i].x1+(int)(ra*st->sinus[n])+(st->kugeln[i].r1-ra)/2;
579 track[nr].y=st->kugeln[i].y1+(int)(ra*st->cosinus[n])+(st->kugeln[i].r1-ra)/2;
581 XFillPolygon(st->dpy,buf,st->gc,track,nr,Convex,CoordModeOrigin);
583 #else /* Use XFillArc */
584 XFillArc(st->dpy, buf, st->gc,
585 (int)(st->kugeln[i].x1+(st->kugeln[i].r1+ra)/2),
586 (int)(st->kugeln[i].y1+(st->kugeln[i].r1+ra)/2),
587 (int)-(2*ra+1), (int)-(2*ra+1), 0, 360*64);
593 /*------------------------------------------------------------------*/
596 init_3d(struct state *st)
617 for (i=0.0;n<sines;i+=TWOPI/sines,n++)
620 st->cosinus[n]=cos(i);
623 /*------------------------------------------------------------------*/
627 vektorprodukt(double feld1[], double feld2[], double feld3[])
629 feld3[0]=feld1[1]*feld2[2]-feld1[2]*feld2[1];
630 feld3[1]=feld1[2]*feld2[0]-feld1[0]*feld2[2];
631 feld3[2]=feld1[0]*feld2[1]-feld1[1]*feld2[0];
635 /*------------------------------------------------------------------*/
637 turn(double feld1[], double feld2[], double winkel)
640 double s,ca,sa,sx1,sx2,sx3;
642 vektorprodukt(feld1,feld2,temp);
644 s=feld1[0]*feld2[0]+feld1[1]*feld2[1]+feld1[2]*feld2[2];
649 sa=sin(winkel);ca=cos(winkel);
650 feld1[0]=ca*(feld1[0]-sx1)+sa*temp[0]+sx1;
651 feld1[1]=ca*(feld1[1]-sx2)+sa*temp[1]+sx2;
652 feld1[2]=ca*(feld1[2]-sx3)+sa*temp[2]+sx3;
654 /*------------------------------------------------------------------*/
656 /* 1: Blickrichtung v;3:Ebenenmittelpunkt m
657 double feld1[],feld3[]; */
659 viewpoint(struct state *st)
661 st->am[0]=-st->zoom*st->v[0];
662 st->am[1]=-st->zoom*st->v[1];
663 st->am[2]=-st->zoom*st->v[2];
665 st->zaehler=norm*norm*st->zoom;
668 /*------------------------------------------------------------------*/
670 projektion(struct state *st)
672 double c1[3],c2[3],k[3],x1,y1;
673 double cno,cnorm/*,magnit*/;
676 for (i=0;i<st->maxk;i++)
678 c1[0]=st->kugeln[i].x-st->a[0];
679 c1[1]=st->kugeln[i].y-st->a[1];
680 c1[2]=st->kugeln[i].z-st->a[2];
681 cnorm=sqrt(c1[0]*c1[0]+c1[1]*c1[1]+c1[2]*c1[2]);
687 cno=c2[0]*st->v[0]+c2[1]*st->v[1]+c2[2]*st->v[2];
688 st->kugeln[i].d=cnorm;
689 if (cno<0) st->kugeln[i].d=-20.0;
692 st->kugeln[i].r1=(st->mag*st->zoom*st->kugeln[i].r/cnorm);
698 vektorprodukt(c2,c1,k);
701 x1=(st->startx+(st->x[0]*k[0]+st->x[1]*k[1]+st->x[2]*k[2])*st->mag);
702 y1=(st->starty-(st->y[0]*k[0]+st->y[1]*k[1]+st->y[2]*k[2])*st->mag);
704 && (x1<st->scrnWidth+2000.0)
706 && (y1<st->scrnHeight+2000.0))
708 st->kugeln[i].x1=(int)x1;
709 st->kugeln[i].y1=(int)y1;
715 st->kugeln[i].d=-20.0;
722 t3d_init (Display *dpy, Window window)
724 struct state *st = (struct state *) calloc (1, sizeof(*st));
731 initColor(st,st->r,st->g,st->b);
733 st->zeit=(struct tm *)malloc(sizeof(struct tm));
736 st->startx=st->scrnWidth/2;
737 st->starty=st->scrnHeight/2;
738 st->scrnH2=st->startx;
739 st->scrnW2=st->starty;
743 vektorprodukt(st->x,st->y,st->v);
744 viewpoint(st/*m,v*/);
746 setink (BlackPixelOfScreen(st->xgwa.screen));
747 XFillRectangle (st->dpy, st->window, st->gc, 0, 0, st->scrnWidth, st->scrnHeight);
748 XQueryPointer (st->dpy, st->window, &st->junk_win, &st->junk_win, &st->junk, &st->junk,
749 &st->px, &st->py, &st->kb);
755 t3d_draw (Display *d, Window w, void *closure)
757 struct state *st = (struct state *) closure;
762 /*--------------- Zeichenteil --------------*/
764 vektorprodukt(st->x,st->y,st->v);
766 vnorm=sqrt(st->v[0]*st->v[0]+st->v[1]*st->v[1]+st->v[2]*st->v[2]);
767 st->v[0]=st->v[0]*norm/vnorm;
768 st->v[1]=st->v[1]*norm/vnorm;
769 st->v[2]=st->v[2]*norm/vnorm;
770 vnorm=sqrt(st->x[0]*st->x[0]+st->x[1]*st->x[1]+st->x[2]*st->x[2]);
771 st->x[0]=st->x[0]*norm/vnorm;
772 st->x[1]=st->x[1]*norm/vnorm;
773 st->x[2]=st->x[2]*norm/vnorm;
774 vnorm=sqrt(st->y[0]*st->y[0]+st->y[1]*st->y[1]+st->y[2]*st->y[2]);
775 st->y[0]=st->y[0]*norm/vnorm;
776 st->y[1]=st->y[1]*norm/vnorm;
777 st->y[2]=st->y[2]*norm/vnorm;
780 t3d_sort (st,0,st->maxk-1);
786 st->draw_color=(int)(64.0*(dtime/60-floor(dtime/60)))-32;
789 st->draw_color=-st->draw_color;
791 setink(st->colors[st->draw_color/3].pixel);
794 setink(BlackPixelOfScreen (st->xgwa.screen));
796 XFillRectangle(st->dpy,st->buffer,st->gc,0,0,st->scrnWidth,st->scrnHeight);
801 manipulate(st,dtime);
803 for (i=0;i<st->maxk;i++)
805 if (st->kugeln[i].d>0.0)
806 fill_kugel(st,i,st->buffer,1);
810 /* manipulate(gettime());
812 if (var>=TWOPI) var=PI/500; */
816 dtime=st->hsvcycl*dtime/10.0+st->hue/360.0;
817 dtime=360*(dtime-floor(dtime));
819 hsv2rgb(dtime,st->sat,st->val,&st->r,&st->g,&st->b);
820 changeColor(st,st->r,st->g,st->b);
823 XCopyArea (st->dpy, st->buffer, st->window, st->gc, 0, 0, st->scrnWidth, st->scrnHeight, 0, 0);
826 /*-------------------------------------------------*/
828 XQueryPointer (st->dpy, st->window, &st->junk_win, &st->in_win, &st->junk, &st->junk,
829 &st->px, &st->py, &st->kb);
831 if ((st->px>0)&&(st->px<st->scrnWidth)&&(st->py>0)&&(st->py<st->scrnHeight) )
833 if ((st->px !=st->startx)&&(st->kb&Button2Mask))
835 /* printf("y=(%f,%f,%f)",y[0],y[1],y[2]);*/
836 turn(st->y,st->x,((double)(st->px-st->startx))/(8000*st->mag));
837 /* printf("->(%f,%f,%f)\n",y[0],y[1],y[2]);*/
839 if ((st->py !=st->starty)&&(st->kb&Button2Mask))
841 /* printf("x=(%f,%f,%f)",x[0],x[1],x[2]);*/
842 turn(st->x,st->y,((double)(st->py-st->starty))/(-8000*st->mag));
843 /* printf("->(%f,%f,%f)\n",x[0],x[1],x[2]);*/
845 if ((st->kb&Button1Mask))
847 if (st->vturn==0.0) st->vturn=.005; else if (st->vturn<2) st->vturn+=.01;
848 turn(st->x,st->v,.002*st->vturn);
849 turn(st->y,st->v,.002*st->vturn);
851 if ((st->kb&Button3Mask))
853 if (st->vturn==0.0) st->vturn=.005; else if (st->vturn<2) st->vturn+=.01;
854 turn(st->x,st->v,-.002*st->vturn);
855 turn(st->y,st->v,-.002*st->vturn);
858 if (!(st->kb&Button1Mask)&&!(st->kb&Button3Mask))
861 st->speed=st->speed+st->speed*st->vspeed;
862 if ((st->speed<0.0000001) &&(st->vspeed>0.000001)) st->speed=0.000001;
863 st->vspeed=.1*st->vspeed;
864 if (st->speed>0.01) st->speed=.01;
865 st->a[0]=st->a[0]+st->speed*st->v[0];
866 st->a[1]=st->a[1]+st->speed*st->v[1];
867 st->a[2]=st->a[2]+st->speed*st->v[2];
873 t3d_reshape (Display *dpy, Window window, void *closure,
874 unsigned int w, unsigned int h)
876 struct state *st = (struct state *) closure;
877 if (w != st->scrnWidth ||
880 XFreePixmap (st->dpy, st->buffer);
883 st->buffer = XCreatePixmap (st->dpy, st->window, st->scrnWidth, st->scrnHeight, st->xgwa.depth);
885 st->startx=st->scrnWidth/2;
886 st->starty=st->scrnHeight/2;
887 st->scrnH2=st->startx;
888 st->scrnW2=st->starty;
893 t3d_event (Display *dpy, Window window, void *closure, XEvent *event)
895 struct state *st = (struct state *) closure;
896 if (event->type == KeyPress)
900 XLookupString (&event->xkey, &kpr, 1, &keysym, 0);
927 t3d_free (Display *dpy, Window window, void *closure)
934 /*-------------------------------------------------*/
936 static const char *t3d_defaults [] = {
937 ".background: black",
938 ".foreground: white",
953 static XrmOptionDescRec t3d_options [] = {
954 { "-move", ".move", XrmoptionSepArg, 0 },
955 { "-wobble", ".wobble", XrmoptionSepArg, 0 },
956 { "-cycle", ".cycle", XrmoptionSepArg, 0 },
957 { "-mag", ".mag", XrmoptionSepArg, 0 },
958 { "-minutes", ".minutes", XrmoptionNoArg, "True" },
959 { "-no-minutes", ".minutes", XrmoptionNoArg, "False" },
960 { "-delay", ".delay", XrmoptionSepArg, 0 },
961 { "-fast", ".fast", XrmoptionSepArg, 0 },
962 { "-colcycle", ".colcycle", XrmoptionSepArg, 0 },
963 { "-hsvcycle", ".hsvcycle", XrmoptionSepArg, 0 },
964 { "-rgb", ".rgb", XrmoptionSepArg, 0 },
965 { "-hsv", ".hsv", XrmoptionSepArg, 0 },
970 XSCREENSAVER_MODULE ("T3D", t3d)