X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Ft3d.c;h=65beb6d92aa35a928cca7f264246066c2b39be5c;hp=8b7ee7ed6f64b3cfad0a012f5fc552eeb2bad99a;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/t3d.c b/hacks/t3d.c index 8b7ee7ed..65beb6d9 100644 --- a/hacks/t3d.c +++ b/hacks/t3d.c @@ -13,9 +13,10 @@ of the command-line options provided by screenhack.c. */ -#define FASTDRAW -#define FASTCOPY -#undef USE_POLYGON +#ifndef HAVE_COCOA +# define FASTDRAW +# define FASTCOPY +#endif /* !HAVE_COCOA */ #include #include @@ -24,37 +25,33 @@ #include "screenhack.h" -static int maxk=34; - #define WIDTH 200 #define HEIGHT 200 #define norm 20.0 -int timewait=40000; - #define ROOT 0x1 #define PI M_PI #define TWOPI 2*M_PI #define MIN(i,j) ((i)<(j)?(i):(j)) -#define kmax ((minutes?60:24)) +#define kmax ((st->minutes?60:24)) /* Anzahl der Kugeln */ #define sines 52 /* Werte in der Sinus-Tabelle */ /*-----------------------------------------------------------------*/ #define setink(inkcolor) \ - XSetForeground (dpy,gc,inkcolor) + XSetForeground (st->dpy,st->gc,inkcolor) #define drawline(xx1,yy1,xx2,yy2) \ - XDrawLine(dpy,win,gc,xx1,yy1,xx2,yy2) + XDrawLine(st->dpy,st->win,st->gc,xx1,yy1,xx2,yy2) #define drawseg(segments,nr_segments) \ - XDrawSegments(dpy,win,gc,segments,nr_segments) + XDrawSegments(st->dpy,st->win,st->gc,segments,nr_segments) #define polyfill(ppts,pcount) \ - XFillPolygon(dpy,win,gc,ppts,pcount,Convex,CoordModeOrigin) + XFillPolygon(st->dpy,st->win,st->gc,ppts,pcount,Convex,CoordModeOrigin) #define frac(argument) argument-floor(argument) @@ -62,11 +59,6 @@ int timewait=40000; #undef ABS #define ABS(x) ((x)<0.0 ? -(x) : (x)) -static Colormap cmap; -/* static XColor gray1; */ -static double r=1.0,g=1.0,b=1.0; -static double hue=0.0,sat=0.0,val=1.0; - typedef struct { double x,y,z,r,d,r1; int x1,y1; @@ -74,65 +66,75 @@ typedef struct { /* Felder fuer 3D */ -static kugeldat kugeln[100]; - -static double a[3],/*m[3],*/am[3],x[3],y[3],v[3]; -static double zoom,speed,zaehler,vspeed/*,AE*/; -static double vturn/*,aturn*/; -/* static XPoint track[sines]; */ -static double sinus[sines]; -static double cosinus[sines]; - -static int startx,starty; -static double /*magx,magy,*/mag=10; -/* static double lastx,lasty,lastz; */ -/* static int lastcx,lastcy,lastcz; */ -/* static int move=1; */ -static int minutes=0; -static int cycl=0; -static double hsvcycl=0.0; -static double movef =0.5, wobber=2.0, cycle=6.0; - -/* time */ - -/* static double sec; */ - -/* Windows */ -static XWindowAttributes xgwa; -static GC gc; -static GC orgc; -static GC andgc; -static Window win; -/* static Font font; */ -static Display *dpy; -static int screen, scrnWidth = WIDTH, scrnHeight = HEIGHT; -static Pixmap buffer; -#define maxfast 100 -static int fastch=50; -#ifdef FASTDRAW -# ifdef FASTCOPY -# define sum1ton(a) (((a)*(a)+1)/2) -# define fastcw sum1ton(fastch) - static Pixmap fastcircles; - static Pixmap fastmask; -# else - static XImage* fastcircles[maxfast]; - static XImage* fastmask[maxfast]; -# endif -static int fastdraw=0; -#endif -static int scrnW2,scrnH2; -/* static unsigned short flags = 0; */ -/* static char *text; */ -static XColor colors[64]; -static struct tm *zeit; +struct state { + Display *dpy; + Window window; + + int maxk; + int timewait; + + Colormap cmap; + double r,g,b; + double hue,sat,val; + + kugeldat kugeln[100]; + + double a[3],am[3],x[3],y[3],v[3]; + double zoom,speed,zaehler,vspeed; + double vturn; + double sinus[sines]; + double cosinus[sines]; + + int startx,starty; + double mag; + int minutes; + int cycl; + double hsvcycl; + double movef, wobber, cycle; + + XWindowAttributes xgwa; + GC gc; + GC orgc; + GC andgc; + int scrnWidth, scrnHeight; + Pixmap buffer; + int fastch; + + int scrnW2,scrnH2; + XColor colors[64]; + struct tm *zeit; + + int planes; + + Window junk_win,in_win; + int px,py,junk; + unsigned int kb; + + int fastdraw; + int draw_color; + +# ifdef FASTDRAW +# ifdef FASTCOPY +# define sum1ton(a) (((a)*(a)+1)/2) +# define fastcw sum1ton(st->fastch) + Pixmap fastcircles; + Pixmap fastmask; +# else /* !FASTCOPY */ + XImage* fastcircles[maxfast]; + XImage* fastmask[maxfast]; +# endif /* !FASTCOPY */ +# endif /* FASTDRAW */ +}; + + + +#define maxfast 100 -static int planes; /* compute time */ static double -gettime (void) +gettime (struct state *st) { struct timeval time1; struct tm *zeit; @@ -188,53 +190,53 @@ hsv2rgb (double h, double s, double v, double *r, double *g, double *b) } static void -changeColor (double r, double g, double b) +changeColor (struct state *st, double r, double g, double b) { int n,n1; n1=0; for(n=30;n<64;n+=3) { - colors[n1].red =1023+ n*(int)(1024.*r); - colors[n1].blue =1023+ n*(int)(1024.*b); - colors[n1].green =1023+ n*(int)(1024.*g); + st->colors[n1].red =1023+ n*(int)(1024.*r); + st->colors[n1].blue =1023+ n*(int)(1024.*b); + st->colors[n1].green =1023+ n*(int)(1024.*g); n1++; } - XStoreColors (dpy, cmap, colors, 12); + XStoreColors (st->dpy, st->cmap, st->colors, 12); } static void -initColor (double r, double g, double b) +initColor (struct state *st, double r, double g, double b) { int n,n1; unsigned long pixels[12]; unsigned long dummy; - cmap = xgwa.colormap; + st->cmap = st->xgwa.colormap; - if(hsvcycl!=0.0 && XAllocColorCells(dpy, cmap, 0, &dummy, 0, pixels, 12)) + if(st->hsvcycl!=0.0 && XAllocColorCells(st->dpy, st->cmap, 0, &dummy, 0, pixels, 12)) { for(n1=0;n1<12;n1++) { - colors[n1].pixel=pixels[n1]; - colors[n1].flags=DoRed | DoGreen | DoBlue; + st->colors[n1].pixel=pixels[n1]; + st->colors[n1].flags=DoRed | DoGreen | DoBlue; } - changeColor(r,g,b); + changeColor(st,r,g,b); } else { n1=0; for(n=30;n<64;n+=3) { - colors[n1].red =1023+ n*(int)(1024.*r); - colors[n1].blue =1023+ n*(int)(1024.*b); - colors[n1].green =1023+ n*(int)(1024.*g); + st->colors[n1].red =1023+ n*(int)(1024.*r); + st->colors[n1].blue =1023+ n*(int)(1024.*b); + st->colors[n1].green =1023+ n*(int)(1024.*g); - if (!(XAllocColor (dpy, cmap, &colors[n1]))) { - (void) fprintf (stderr, "Error: Cannot allocate colors\n"); + if (!(XAllocColor (st->dpy, st->cmap, &st->colors[n1]))) { + fprintf (stderr, "Error: Cannot allocate colors\n"); exit (1); } @@ -246,81 +248,94 @@ initColor (double r, double g, double b) /* ----------------WINDOW-------------------*/ static void -initialize (void) +initialize (struct state *st) { XGCValues *xgc; XGCValues *xorgc; XGCValues *xandgc; - XGetWindowAttributes (dpy, win, &xgwa); - scrnWidth = xgwa.width; - scrnHeight = xgwa.height; + st->maxk=34; + st->r = st->g = st->b = 1; + st->hue = st->sat = 0; + st->val = 1; + st->mag = 10; + st->movef = 0.5; + st->wobber = 2; + st->cycle = 6; + st->scrnWidth = WIDTH; + st->scrnHeight = HEIGHT; + + + XGetWindowAttributes (st->dpy, st->window, &st->xgwa); + st->scrnWidth = st->xgwa.width; + st->scrnHeight = st->xgwa.height; { - float f = get_float_resource ("cycle", "Float"); + float f = get_float_resource (st->dpy, "cycle", "Float"); if (f <= 0 || f > 60) f = 6.0; - cycle = 60.0 / f; + st->cycle = 60.0 / f; } - movef = get_float_resource ("move", "Float"); - wobber = get_float_resource ("wobble", "Float"); + st->movef = get_float_resource (st->dpy, "move", "Float"); + st->wobber = get_float_resource (st->dpy, "wobble", "Float"); { - double magfac = get_float_resource ("mag", "Float"); - mag *= magfac; - fastch=(int)(fastch*magfac); + double magfac = get_float_resource (st->dpy, "mag", "Float"); + st->mag *= magfac; + st->fastch=(int)(st->fastch*magfac); } - if (get_boolean_resource ("minutes", "Boolean")) { - minutes=1; maxk+=60-24; + if (get_boolean_resource (st->dpy, "minutes", "Boolean")) { + st->minutes=1; st->maxk+=60-24; } - timewait = get_integer_resource ("delay", "Integer"); - fastch = get_integer_resource ("fast", "Integer"); - cycl = get_boolean_resource ("colcycle", "Integer"); - hsvcycl = get_float_resource ("hsvcycle", "Integer"); + st->timewait = get_integer_resource (st->dpy, "delay", "Integer"); + st->fastch = get_integer_resource (st->dpy, "fast", "Integer"); + st->cycl = get_boolean_resource (st->dpy, "colcycle", "Integer"); + st->hsvcycl = get_float_resource (st->dpy, "hsvcycle", "Integer"); { - char *s = get_string_resource ("rgb", "RGB"); + char *s = get_string_resource (st->dpy, "rgb", "RGB"); char dummy; if (s && *s) { double rr, gg, bb; if (3 == sscanf (s, "%lf %lf %lf %c", &rr, &gg, &bb, &dummy)) - r = rr, g = gg, b = bb; + st->r = rr, st->g = gg, st->b = bb; } if (s) free (s); - s = get_string_resource ("hsv", "HSV"); + s = get_string_resource (st->dpy, "hsv", "HSV"); if (s && *s) { double hh, ss, vv; if (3 == sscanf (s, "%lf %lf %lf %c", &hh, &ss, &vv, &dummy)) { - hue = hh, sat = ss, val = vv; - hsv2rgb(hue,sat,val,&r,&g,&b); + st->hue = hh, st->sat = ss, st->val = vv; + hsv2rgb(st->hue,st->sat,st->val,&st->r,&st->g,&st->b); } } if (s) free (s); } - if (fastch>maxfast) - fastch=maxfast; + if (st->fastch > maxfast) + st->fastch=maxfast; xgc=( XGCValues *) malloc(sizeof(XGCValues) ); xorgc=( XGCValues *) malloc(sizeof(XGCValues) ); xandgc=( XGCValues *) malloc(sizeof(XGCValues) ); - screen = screen_number (xgwa.screen); - - planes=xgwa.depth; + st->planes=st->xgwa.depth; - gc = XCreateGC (dpy, win, 0, xgc); +#ifdef HAVE_COCOA +# define GXandInverted GXcopy /* #### this can't be right, right? */ +#endif + st->gc = XCreateGC (st->dpy, st->window, 0, xgc); xorgc->function =GXor; - orgc = XCreateGC (dpy, win, GCFunction, xorgc); + st->orgc = XCreateGC (st->dpy, st->window, GCFunction, xorgc); xandgc->function =GXandInverted; - andgc = XCreateGC (dpy, win, GCFunction, xandgc); + st->andgc = XCreateGC (st->dpy, st->window, GCFunction, xandgc); - buffer = XCreatePixmap (dpy, win, scrnWidth, scrnHeight, - xgwa.depth); + st->buffer = XCreatePixmap (st->dpy, st->window, st->scrnWidth, st->scrnHeight, + st->xgwa.depth); #ifdef DEBUG printf("Time 3D drawing "); @@ -336,73 +351,73 @@ initialize (void) #endif /* DEBUG */ #ifdef FASTCOPY - fastcircles = XCreatePixmap (dpy, win, fastcw, fastch+1, xgwa.depth); - fastmask = XCreatePixmap (dpy, win, fastcw, fastch+1, xgwa.depth); + st->fastcircles = XCreatePixmap (st->dpy, st->window, fastcw, st->fastch+1, st->xgwa.depth); + st->fastmask = XCreatePixmap (st->dpy, st->window, fastcw, st->fastch+1, st->xgwa.depth); #endif - setink(BlackPixel (dpy, screen)); - XFillRectangle (dpy, buffer , gc, 0, 0, scrnWidth, scrnHeight); + setink(BlackPixelOfScreen (st->xgwa.screen)); + XFillRectangle (st->dpy, st->buffer , st->gc, 0, 0, st->scrnWidth, st->scrnHeight); #ifdef FASTCOPY setink(0); - XFillRectangle (dpy, fastcircles, gc, 0, 0, fastcw, fastch+1); - XFillRectangle (dpy, fastmask , gc, 0, 0, fastcw, fastch+1); + XFillRectangle (st->dpy, st->fastcircles, st->gc, 0, 0, fastcw, st->fastch+1); + XFillRectangle (st->dpy, st->fastmask , st->gc, 0, 0, fastcw, st->fastch+1); #endif #ifdef PRTDBX printf("move\t%.2f\nwobber\t%.2f\nmag\t%.2f\ncycle\t%.4f\n", - movef,wobber,mag/10,cycle); - printf("fast\t%i\nmarks\t%i\nwait\t%i\n",fastch,maxk,timewait); + st->movef,st->wobber,st->mag/10,st->cycle); + printf("fast\t%i\nmarks\t%i\nwait\t%i\n",st->fastch,st->maxk,st->timewait); #endif } -static void fill_kugel(int i, Pixmap buf, int setcol); +static void fill_kugel(struct state *st, int i, Pixmap buf, int setcol); /*------------------------------------------------------------------*/ static void -init_kugel(void) +init_kugel(struct state *st) { #ifdef FASTDRAW int i; - for(i=0; ifastch; i++) { # ifdef FASTCOPY - kugeln[i].r1=-((double) i)/2 -1; - kugeln[i].x1=sum1ton(i); - kugeln[i].y1=((double) i)/2 +1; + st->kugeln[i].r1=-((double) i)/2 -1; + st->kugeln[i].x1=sum1ton(i); + st->kugeln[i].y1=((double) i)/2 +1; - fill_kugel(i,fastcircles,1); - setink((1<fastcircles,1); + setink((1<xgwa.depth))-1); + fill_kugel(st,i,st->fastmask,0); # else - kugeln[i].r1=-((double) i)/2 -1; - kugeln[i].x1=kugeln[i].y1=((double) i)/2 +1; + st->kugeln[i].r1=-((double) i)/2 -1; + st->kugeln[i].x1=st->kugeln[i].y1=((double) i)/2 +1; - fill_kugel(i,buffer,1); - fastcircles[i]=XGetImage(dpy,buffer,0,0,i+2,i+2,(1<buffer,1); + st->fastcircles[i]=XGetImage(st->dpy,st->buffer,0,0,i+2,i+2,(1<planes)-1,ZPixmap); - setink((1<xgwa.depth))-1); + fill_kugel(i,st->buffer,0); + st->fastmask[i]=XGetImage(st->dpy,st->buffer,0,0,i+2,i+2,(1<planes)-1,ZPixmap); setink(0); - XFillRectangle (dpy, buffer , gc, 0, 0, scrnWidth, scrnHeight); + XFillRectangle (st->dpy, st->buffer , st->gc, 0, 0, st->scrnWidth, st->scrnHeight); # endif } - fastdraw=1; + st->fastdraw=1; #endif } /* Zeiger zeichnen */ static void -zeiger(double dist,double rad, double z, double sec, int *q) +zeiger(struct state *st, double dist,double rad, double z, double sec, int *q) { int i,n; double gratio=sqrt(2.0/(1.0+sqrt(5.0))); @@ -411,10 +426,10 @@ zeiger(double dist,double rad, double z, double sec, int *q) for(i=0;i<3;i++) { - kugeln[n].x=dist*cos(sec); - kugeln[n].y=-dist*sin(sec); - kugeln[n].z=z; - kugeln[n].r=rad; + st->kugeln[n].x=dist*cos(sec); + st->kugeln[n].y=-dist*sin(sec); + st->kugeln[n].z=z; + st->kugeln[n].r=rad; n++; dist += rad; @@ -428,7 +443,7 @@ zeiger(double dist,double rad, double z, double sec, int *q) *-----------------------------------------------------------------*/ static void -manipulate(double k) +manipulate(struct state *st, double k) { double i,l,/*xs,*/ys,zs,mod; double /*persec,*/sec,min,hour; @@ -443,102 +458,102 @@ manipulate(double k) for (n=0;nkugeln[n].x=4.0*sin(i); + st->kugeln[n].y=4.0*cos(i); + st->kugeln[n].z=st->wobber* /* (sin(floor(2+2*l/(PI))*i)*sin(2*l)); */ cos((i-sec)*floor(2+5*l/(PI)))*sin(5*l); - if(minutes) + if(st->minutes) { - kugeln[n].r=/* (1.0+0.3*cos(floor(2+2*l/(PI))*i)*sin(2*l))* */ + st->kugeln[n].r=/* (1.0+0.3*cos(floor(2+2*l/(PI))*i)*sin(2*l))* */ ((n % 5!=0) ? 0.3 : 0.6)* ((n % 15 ==0) ? 1.25 : .75); } else { - kugeln[n].r=/* (1.0+0.3*cos(floor(2+2*l/(PI))*i)*sin(2*l))* */ + st->kugeln[n].r=/* (1.0+0.3*cos(floor(2+2*l/(PI))*i)*sin(2*l))* */ ((n & 1) ? 0.5 : 1.0)* ((n % 6==0) ? 1.25 : .75); } i+=TWOPI/kmax; } - kugeln[n].x=0.0; - kugeln[n].y=0.0; - kugeln[n].z=0.0; - kugeln[n].r=2.0+cos(TWOPI*modf(k,&mod))/2; + st->kugeln[n].x=0.0; + st->kugeln[n].y=0.0; + st->kugeln[n].z=0.0; + st->kugeln[n].r=2.0+cos(TWOPI*modf(k,&mod))/2; n++; - zeiger(2.0,0.75,-2.0,sec,&n); - zeiger(1.0,1.0,-1.5,min,&n); - zeiger(0.0,1.5,-1.0,hour,&n); + zeiger(st,2.0,0.75,-2.0,sec,&n); + zeiger(st,1.0,1.0,-1.5,min,&n); + zeiger(st,0.0,1.5,-1.0,hour,&n); - for(n=0;nmaxk;n++) { - ys=kugeln[n].y*cos(movef*sin(cycle*sec))+ - kugeln[n].z*sin(movef*sin(cycle*sec)); - zs=-kugeln[n].y*sin(movef*sin(cycle*sec))+ - kugeln[n].z*cos(movef*sin(cycle*sec)); - kugeln[n].y=ys; - kugeln[n].z=zs; + ys=st->kugeln[n].y*cos(st->movef*sin(st->cycle*sec))+ + st->kugeln[n].z*sin(st->movef*sin(st->cycle*sec)); + zs=-st->kugeln[n].y*sin(st->movef*sin(st->cycle*sec))+ + st->kugeln[n].z*cos(st->movef*sin(st->cycle*sec)); + st->kugeln[n].y=ys; + st->kugeln[n].z=zs; } } /*------------------------------------------------------------------*/ static void -t3d_sort(int l, int r) +t3d_sort(struct state *st, int l, int r) { int i,j; kugeldat ex; double x; i=l;j=r; - x=kugeln[(l+r)/2].d; + x=st->kugeln[(l+r)/2].d; while(1) { - while(kugeln[i].d>x) i++; - while(x>kugeln[j].d) j--; + while(st->kugeln[i].d>x) i++; + while(x>st->kugeln[j].d) j--; if (i<=j) { - ex=kugeln[i];kugeln[i]=kugeln[j];kugeln[j]=ex; + ex=st->kugeln[i];st->kugeln[i]=st->kugeln[j];st->kugeln[j]=ex; i++;j--; } if (i>j) break; } - if (lkugeln[i].r1)*2)); if (d==0) d=1; #ifdef FASTDRAW - if(fastdraw && dfastdraw && dfastch) { # ifdef FASTCOPY - XCopyArea(dpy, fastmask, buf, andgc, sum1ton(d)-(d+1)/2, 1,d,d, - (int)(kugeln[i].x1)-d/2, (int)(kugeln[i].y1)-d/2); - XCopyArea(dpy, fastcircles, buf, orgc, sum1ton(d)-(d+1)/2, 1,d,d, - (int)(kugeln[i].x1)-d/2, (int)(kugeln[i].y1)-d/2); + XCopyArea(st->dpy, st->fastmask, buf, st->andgc, sum1ton(d)-(d+1)/2, 1,d,d, + (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2); + XCopyArea(st->dpy, st->fastcircles, buf, st->orgc, sum1ton(d)-(d+1)/2, 1,d,d, + (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2); # else - XPutImage(dpy, buf, andgc, fastmask[d-1], 0, 0, - (int)(kugeln[i].x1)-d/2, (int)(kugeln[i].y1)-d/2, d, d); - XPutImage(dpy, buf, orgc, fastcircles[d-1], 0, 0, - (int)(kugeln[i].x1)-d/2, (int)(kugeln[i].y1)-d/2, d, d); + XPutImage(st->dpy, buf, st->andgc, st->fastmask[d-1], 0, 0, + (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2, d, d); + XPutImage(st->dpy, buf, st->orgc, st->fastcircles[d-1], 0, 0, + (int)(st->kugeln[i].x1)-d/2, (int)(st->kugeln[i].y1)-d/2, d, d); # endif } else #endif { - if(ABS(kugeln[i].r1)<6.0) inr=9; + if(ABS(st->kugeln[i].r1)<6.0) inr=9; for (m=0;m<=28;m+=inr) { - ra=kugeln[i].r1*sqrt(1-m*m/(28.0*28.0)); + ra=st->kugeln[i].r1*sqrt(1-m*m/(28.0*28.0)); #ifdef PRTDBX printf("Radius: %f\n",ra); #endif @@ -552,7 +567,7 @@ fill_kugel(int i, Pixmap buf, int setcol) else col=(int)(m); if (col>33) col=33; col/=3; - setink(colors[col].pixel); + setink(st->colors[col].pixel); } #ifdef USE_POLYGON @@ -560,15 +575,15 @@ fill_kugel(int i, Pixmap buf, int setcol) int n, nr; for (n=0,nr=0;n<=sines-1;n+=inc,nr++) { - track[nr].x=kugeln[i].x1+(int)(ra*sinus[n])+(kugeln[i].r1-ra)/2; - track[nr].y=kugeln[i].y1+(int)(ra*cosinus[n])+(kugeln[i].r1-ra)/2; + track[nr].x=st->kugeln[i].x1+(int)(ra*st->sinus[n])+(st->kugeln[i].r1-ra)/2; + track[nr].y=st->kugeln[i].y1+(int)(ra*st->cosinus[n])+(st->kugeln[i].r1-ra)/2; } - XFillPolygon(dpy,buf,gc,track,nr,Convex,CoordModeOrigin); + XFillPolygon(st->dpy,buf,st->gc,track,nr,Convex,CoordModeOrigin); } #else /* Use XFillArc */ - XFillArc(dpy, buf, gc, - (int)(kugeln[i].x1+(kugeln[i].r1+ra)/2), - (int)(kugeln[i].y1+(kugeln[i].r1+ra)/2), + XFillArc(st->dpy, buf, st->gc, + (int)(st->kugeln[i].x1+(st->kugeln[i].r1+ra)/2), + (int)(st->kugeln[i].y1+(st->kugeln[i].r1+ra)/2), (int)-(2*ra+1), (int)-(2*ra+1), 0, 360*64); #endif } @@ -578,31 +593,31 @@ fill_kugel(int i, Pixmap buf, int setcol) /*------------------------------------------------------------------*/ static void -init_3d(void) +init_3d(struct state *st) { double i; int n=0; - a[0]=0.0; - a[1]=0.0; - a[2]=-10.0; + st->a[0]=0.0; + st->a[1]=0.0; + st->a[2]=-10.0; - x[0]=10.0; - x[1]=0.0; - x[2]=0.0; + st->x[0]=10.0; + st->x[1]=0.0; + st->x[2]=0.0; - y[0]=0.0; - y[1]=10.0; - y[2]=0.0; + st->y[0]=0.0; + st->y[1]=10.0; + st->y[2]=0.0; - zoom=-10.0; - speed=.0; + st->zoom=-10.0; + st->speed=.0; for (i=0.0;nsinus[n]=sin(i); + st->cosinus[n]=cos(i); } } /*------------------------------------------------------------------*/ @@ -615,6 +630,8 @@ vektorprodukt(double feld1[], double feld2[], double feld3[]) feld3[1]=feld1[2]*feld2[0]-feld1[0]*feld2[2]; feld3[2]=feld1[0]*feld2[1]-feld1[1]*feld2[0]; } + + /*------------------------------------------------------------------*/ static void turn(double feld1[], double feld2[], double winkel) @@ -639,149 +656,283 @@ turn(double feld1[], double feld2[], double winkel) /* 1: Blickrichtung v;3:Ebenenmittelpunkt m double feld1[],feld3[]; */ static void -viewpoint(void) +viewpoint(struct state *st) { - am[0]=-zoom*v[0]; - am[1]=-zoom*v[1]; - am[2]=-zoom*v[2]; + st->am[0]=-st->zoom*st->v[0]; + st->am[1]=-st->zoom*st->v[1]; + st->am[2]=-st->zoom*st->v[2]; - zaehler=norm*norm*zoom; + st->zaehler=norm*norm*st->zoom; } + /*------------------------------------------------------------------*/ static void -projektion(void) +projektion(struct state *st) { double c1[3],c2[3],k[3],x1,y1; double cno,cnorm/*,magnit*/; int i; - for (i=0;imaxk;i++) { - c1[0]=kugeln[i].x-a[0]; - c1[1]=kugeln[i].y-a[1]; - c1[2]=kugeln[i].z-a[2]; + c1[0]=st->kugeln[i].x-st->a[0]; + c1[1]=st->kugeln[i].y-st->a[1]; + c1[2]=st->kugeln[i].z-st->a[2]; cnorm=sqrt(c1[0]*c1[0]+c1[1]*c1[1]+c1[2]*c1[2]); c2[0]=c1[0]; c2[1]=c1[1]; c2[2]=c1[2]; - cno=c2[0]*v[0]+c2[1]*v[1]+c2[2]*v[2]; - kugeln[i].d=cnorm; - if (cno<0) kugeln[i].d=-20.0; + cno=c2[0]*st->v[0]+c2[1]*st->v[1]+c2[2]*st->v[2]; + st->kugeln[i].d=cnorm; + if (cno<0) st->kugeln[i].d=-20.0; - kugeln[i].r1=(mag*zoom*kugeln[i].r/cnorm); + st->kugeln[i].r1=(st->mag*st->zoom*st->kugeln[i].r/cnorm); - c2[0]=v[0]/cno; - c2[1]=v[1]/cno; - c2[2]=v[2]/cno; + c2[0]=st->v[0]/cno; + c2[1]=st->v[1]/cno; + c2[2]=st->v[2]/cno; vektorprodukt(c2,c1,k); - x1=(startx+(x[0]*k[0]+x[1]*k[1]+x[2]*k[2])*mag); - y1=(starty-(y[0]*k[0]+y[1]*k[1]+y[2]*k[2])*mag); + x1=(st->startx+(st->x[0]*k[0]+st->x[1]*k[1]+st->x[2]*k[2])*st->mag); + y1=(st->starty-(st->y[0]*k[0]+st->y[1]*k[1]+st->y[2]*k[2])*st->mag); if( (x1>-2000.0) - && (x1scrnWidth+2000.0) && (y1>-2000.0) - && (y1scrnHeight+2000.0)) { - kugeln[i].x1=(int)x1; - kugeln[i].y1=(int)y1; + st->kugeln[i].x1=(int)x1; + st->kugeln[i].y1=(int)y1; } else { - kugeln[i].x1=0; - kugeln[i].y1=0; - kugeln[i].d=-20.0; + st->kugeln[i].x1=0; + st->kugeln[i].y1=0; + st->kugeln[i].d=-20.0; } } } -/*---------- event-handler ----------------*/ -static void -event_handler(void) + +static void * +t3d_init (Display *dpy, Window window) { - while (XEventsQueued (dpy, QueuedAfterReading)) - { - XEvent event; - - XNextEvent (dpy, &event); - switch (event.type) - { - case ConfigureNotify: - if (event.xconfigure.width != scrnWidth || - event.xconfigure.height != scrnHeight) - { - XFreePixmap (dpy, buffer); - scrnWidth = event.xconfigure.width; - scrnHeight = event.xconfigure.height; - buffer = XCreatePixmap (dpy, win, scrnWidth, scrnHeight, - xgwa.depth); - - startx=scrnWidth/2; - starty=scrnHeight/2; - scrnH2=startx; - scrnW2=starty; - }; - break; + struct state *st = (struct state *) calloc (1, sizeof(*st)); + st->dpy = dpy; + st->window = window; + st->dpy = dpy; + st->window = window; + initialize(st); + + initColor(st,st->r,st->g,st->b); + init_3d(st); + st->zeit=(struct tm *)malloc(sizeof(struct tm)); + init_kugel(st); + + st->startx=st->scrnWidth/2; + st->starty=st->scrnHeight/2; + st->scrnH2=st->startx; + st->scrnW2=st->starty; + st->vspeed=0; + + + vektorprodukt(st->x,st->y,st->v); + viewpoint(st/*m,v*/); + + setink (BlackPixelOfScreen(st->xgwa.screen)); + XFillRectangle (st->dpy, st->window, st->gc, 0, 0, st->scrnWidth, st->scrnHeight); + XQueryPointer (st->dpy, st->window, &st->junk_win, &st->junk_win, &st->junk, &st->junk, + &st->px, &st->py, &st->kb); + + return st; +} - case KeyPress: - { - KeySym kpr=XKeycodeToKeysym(dpy,event.xkey.keycode,0); - - switch (kpr) - { - case 's': case 'S': - vspeed = 0.5; - break; - case 'a': case 'A': - vspeed = -0.3; - break; - - case '0': - speed = 0; - vspeed = 0; - break; - - case 'z': case 'Z': - mag *= 1.02; - break; - - case 'x': case 'X': - mag /= 1.02; - break; - - default: - screenhack_handle_event (dpy, &event); - break; - } - } +static unsigned long +t3d_draw (Display *d, Window w, void *closure) +{ + struct state *st = (struct state *) closure; + double dtime; + double vnorm; - case ButtonPress: case ButtonRelease: - break; + + /*--------------- Zeichenteil --------------*/ - default: - screenhack_handle_event (dpy, &event); - break; - } + vektorprodukt(st->x,st->y,st->v); + + vnorm=sqrt(st->v[0]*st->v[0]+st->v[1]*st->v[1]+st->v[2]*st->v[2]); + st->v[0]=st->v[0]*norm/vnorm; + st->v[1]=st->v[1]*norm/vnorm; + st->v[2]=st->v[2]*norm/vnorm; + vnorm=sqrt(st->x[0]*st->x[0]+st->x[1]*st->x[1]+st->x[2]*st->x[2]); + st->x[0]=st->x[0]*norm/vnorm; + st->x[1]=st->x[1]*norm/vnorm; + st->x[2]=st->x[2]*norm/vnorm; + vnorm=sqrt(st->y[0]*st->y[0]+st->y[1]*st->y[1]+st->y[2]*st->y[2]); + st->y[0]=st->y[0]*norm/vnorm; + st->y[1]=st->y[1]*norm/vnorm; + st->y[2]=st->y[2]*norm/vnorm; + + projektion(st); + t3d_sort (st,0,st->maxk-1); + + dtime=gettime(st); + + if(st->cycl) + { + st->draw_color=(int)(64.0*(dtime/60-floor(dtime/60)))-32; + + if(st->draw_color<0) + st->draw_color=-st->draw_color; + + setink(st->colors[st->draw_color/3].pixel); } - /*nap(40);-Ersatz*/ + else + setink(BlackPixelOfScreen (st->xgwa.screen)); + + XFillRectangle(st->dpy,st->buffer,st->gc,0,0,st->scrnWidth,st->scrnHeight); + { - struct timeval timeout; - timeout.tv_sec=timewait/1000000; - timeout.tv_usec=timewait%1000000; - (void)select(0,0,0,0,&timeout); + int i; + + manipulate(st,dtime); + + for (i=0;imaxk;i++) + { + if (st->kugeln[i].d>0.0) + fill_kugel(st,i,st->buffer,1); + } } + + /* manipulate(gettime()); + var+=PI/500; + if (var>=TWOPI) var=PI/500; */ + + if(st->hsvcycl!=0.0) + { + dtime=st->hsvcycl*dtime/10.0+st->hue/360.0; + dtime=360*(dtime-floor(dtime)); + + hsv2rgb(dtime,st->sat,st->val,&st->r,&st->g,&st->b); + changeColor(st,st->r,st->g,st->b); + } + + XCopyArea (st->dpy, st->buffer, st->window, st->gc, 0, 0, st->scrnWidth, st->scrnHeight, 0, 0); + + + /*-------------------------------------------------*/ + + XQueryPointer (st->dpy, st->window, &st->junk_win, &st->in_win, &st->junk, &st->junk, + &st->px, &st->py, &st->kb); + + if ((st->px>0)&&(st->pxscrnWidth)&&(st->py>0)&&(st->pyscrnHeight) ) + { + if ((st->px !=st->startx)&&(st->kb&Button2Mask)) + { + /* printf("y=(%f,%f,%f)",y[0],y[1],y[2]);*/ + turn(st->y,st->x,((double)(st->px-st->startx))/(8000*st->mag)); + /* printf("->(%f,%f,%f)\n",y[0],y[1],y[2]);*/ + } + if ((st->py !=st->starty)&&(st->kb&Button2Mask)) + { + /* printf("x=(%f,%f,%f)",x[0],x[1],x[2]);*/ + turn(st->x,st->y,((double)(st->py-st->starty))/(-8000*st->mag)); + /* printf("->(%f,%f,%f)\n",x[0],x[1],x[2]);*/ + } + if ((st->kb&Button1Mask)) + { + if (st->vturn==0.0) st->vturn=.005; else if (st->vturn<2) st->vturn+=.01; + turn(st->x,st->v,.002*st->vturn); + turn(st->y,st->v,.002*st->vturn); + } + if ((st->kb&Button3Mask)) + { + if (st->vturn==0.0) st->vturn=.005; else if (st->vturn<2) st->vturn+=.01; + turn(st->x,st->v,-.002*st->vturn); + turn(st->y,st->v,-.002*st->vturn); + } + } + if (!(st->kb&Button1Mask)&&!(st->kb&Button3Mask)) + st->vturn=0; + + st->speed=st->speed+st->speed*st->vspeed; + if ((st->speed<0.0000001) &&(st->vspeed>0.000001)) st->speed=0.000001; + st->vspeed=.1*st->vspeed; + if (st->speed>0.01) st->speed=.01; + st->a[0]=st->a[0]+st->speed*st->v[0]; + st->a[1]=st->a[1]+st->speed*st->v[1]; + st->a[2]=st->a[2]+st->speed*st->v[2]; + + return st->timewait; +} + +static void +t3d_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct state *st = (struct state *) closure; + if (w != st->scrnWidth || + h != st->scrnHeight) + { + XFreePixmap (st->dpy, st->buffer); + st->scrnWidth = w; + st->scrnHeight = h; + st->buffer = XCreatePixmap (st->dpy, st->window, st->scrnWidth, st->scrnHeight, st->xgwa.depth); + + st->startx=st->scrnWidth/2; + st->starty=st->scrnHeight/2; + st->scrnH2=st->startx; + st->scrnW2=st->starty; + } +} + +static Bool +t3d_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + struct state *st = (struct state *) closure; + if (event->type == KeyPress) + { + KeySym kpr=XKeycodeToKeysym(st->dpy,event->xkey.keycode,0); + + switch (kpr) + { + case 's': case 'S': + st->vspeed = 0.5; + return True; + case 'a': case 'A': + st->vspeed = -0.3; + return True; + case '0': + st->speed = 0; + st->vspeed = 0; + return True; + case 'z': case 'Z': + st->mag *= 1.02; + return True; + case 'x': case 'X': + st->mag /= 1.02; + return True; + default: + break; + } + } + return False; +} + +static void +t3d_free (Display *dpy, Window window, void *closure) +{ } -/*-------------------------------------------------*/ -char *progclass = "T3D"; -char *defaults [] = { +/*-------------------------------------------------*/ + +static const char *t3d_defaults [] = { ".background: black", ".foreground: white", "*move: 0.5", @@ -791,12 +942,14 @@ char *defaults [] = { "*minutes: False", "*delay: 40000", "*fast: 50", - "*ccycle: False", + "*colcycle: False", "*hsvcycle: 0.0", + "*rgb: ", + "*hsv: ", 0 }; -XrmOptionDescRec options [] = { +static XrmOptionDescRec t3d_options [] = { { "-move", ".move", XrmoptionSepArg, 0 }, { "-wobble", ".wobble", XrmoptionSepArg, 0 }, { "-cycle", ".cycle", XrmoptionSepArg, 0 }, @@ -813,159 +966,4 @@ XrmOptionDescRec options [] = { }; -void -screenhack (Display *d, Window w) -{ - Window junk_win,in_win; - - int px,py,junk/*,wai*/; - unsigned int kb; -/* int act,act1,tc;*/ - double vnorm; - /* double var=0.0; */ - int color=0/*, dir=1*/; - - dpy = d; - win = w; - initialize(); - - initColor(r,g,b); - init_3d(); - zeit=(struct tm *)malloc(sizeof(struct tm)); - init_kugel(); - - startx=scrnWidth/2; - starty=scrnHeight/2; - scrnH2=startx; - scrnW2=starty; - vspeed=0; - - - vektorprodukt(x,y,v); - viewpoint(/*m,v*/); - - setink (BlackPixel (dpy, screen)); - XFillRectangle (dpy, win, gc, 0, 0, scrnWidth, scrnHeight); - XQueryPointer (dpy, win, &junk_win, &junk_win, &junk, &junk, - &px, &py, &kb); - - for (;;) - { double dtime; - - /*--------------- Zeichenteil --------------*/ - - event_handler(); - - vektorprodukt(x,y,v); - - vnorm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); - v[0]=v[0]*norm/vnorm; - v[1]=v[1]*norm/vnorm; - v[2]=v[2]*norm/vnorm; - vnorm=sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]); - x[0]=x[0]*norm/vnorm; - x[1]=x[1]*norm/vnorm; - x[2]=x[2]*norm/vnorm; - vnorm=sqrt(y[0]*y[0]+y[1]*y[1]+y[2]*y[2]); - y[0]=y[0]*norm/vnorm; - y[1]=y[1]*norm/vnorm; - y[2]=y[2]*norm/vnorm; - - projektion(); - t3d_sort (0,maxk-1); - - dtime=gettime(); - - if(cycl) - { - color=(int)(64.0*(dtime/60-floor(dtime/60)))-32; - - if(color<0) - color=-color; - - setink(colors[color/3].pixel); - } - else - setink(BlackPixel (dpy, screen)); - - XFillRectangle(dpy,buffer,gc,0,0,scrnWidth,scrnHeight); - - { - int i; - - manipulate(dtime); - - for (i=0;i0.0) - fill_kugel(i,buffer,1); - } - } - - XSync(dpy,0); - - /* manipulate(gettime()); - var+=PI/500; - if (var>=TWOPI) var=PI/500; */ - - /*event_handler();*/ - - if(hsvcycl!=0.0) - { - dtime=hsvcycl*dtime/10.0+hue/360.0; - dtime=360*(dtime-floor(dtime)); - - hsv2rgb(dtime,sat,val,&r,&g,&b); - changeColor(r,g,b); - } - - XCopyArea (dpy, buffer, win, gc, 0, 0, scrnWidth, scrnHeight, 0, 0); - - - /*-------------------------------------------------*/ - XSync(dpy,0); - - event_handler(); - - (void)(XQueryPointer (dpy, win, &junk_win, &in_win, &junk, &junk, - &px, &py, &kb)); - - if ((px>0)&&(px0)&&(py(%f,%f,%f)\n",y[0],y[1],y[2]);*/ - } - if ((py !=starty)&&(kb&Button2Mask)) - { - /* printf("x=(%f,%f,%f)",x[0],x[1],x[2]);*/ - turn(x,y,((double)(py-starty))/(-8000*mag)); - /* printf("->(%f,%f,%f)\n",x[0],x[1],x[2]);*/ - } - if ((kb&Button1Mask)) - { - if (vturn==0.0) vturn=.005; else if (vturn<2) vturn+=.01; - turn(x,v,.002*vturn); - turn(y,v,.002*vturn); - } - if ((kb&Button3Mask)) - { - if (vturn==0.0) vturn=.005; else if (vturn<2) vturn+=.01; - turn(x,v,-.002*vturn); - turn(y,v,-.002*vturn); - } - } - if (!(kb&Button1Mask)&&!(kb&Button3Mask)) - vturn=0; - - speed=speed+speed*vspeed; - if ((speed<0.0000001) &&(vspeed>0.000001)) speed=0.000001; - vspeed=.1*vspeed; - if (speed>0.01) speed=.01; - a[0]=a[0]+speed*v[0]; - a[1]=a[1]+speed*v[1]; - a[2]=a[2]+speed*v[2]; - } -} +XSCREENSAVER_MODULE ("T3D", t3d)