source: trunk/third/xscreensaver/hacks/kumppa.c @ 20148

Revision 20148, 10.3 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2
3Copyright (C) Teemu Suutari (temisu@utu.fi) Feb 1998
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sublicense, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice shall be included
14in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
20OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of the X Consortium shall
25not be used in advertising or otherwise to promote the sale, use or
26other dealings in this Software without prior written authorization
27from the X Consortium.
28
29*/
30
31
32
33
34/*
35
36*** This is contest-version. Don't look any further, code is *very* ugly.
37
38*/
39
40
41#include <math.h>
42#include "screenhack.h"
43
44#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
45# include "xdbe.h"
46#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
47
48char *progclass="Kumppa";
49
50char *defaults [] ={
51        ".background:           black",
52        "*speed:                0.1",
53        "*delay:                10000",
54#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
55        /* leave this off by default, since it slows things down.  -- jwz. */
56        "*useDBE:               False",
57#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
58        0
59};
60
61XrmOptionDescRec options [] = {
62        {"-delay",".delay",XrmoptionSepArg,0},
63        {"-speed",".speed",XrmoptionSepArg,0},
64        {"-random",".random",XrmoptionIsArg,0},
65#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
66        {"-dbuf",".dbuf",XrmoptionIsArg,0},
67#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
68        {0,0,0,0}
69};
70
71const unsigned char colors[96]=
72        {0,0,255, 0,51,255, 0,102,255, 0,153,255, 0,204,255,
73        0,255,255,0,255,204, 0,255,153, 0,255,102, 0,255,51,
74        0,255,0, 51,255,0, 102,255,0, 153,255,0, 204,255,0,
75        255,255,0, 255,204,0, 255,153,0, 255,102,0, 255,51,0,
76        255,0,0, 255,0,51, 255,0,102, 255,0,153, 255,0,204,
77        255,0,255, 219,0,255, 182,0,255, 146,0,255, 109,0,255,
78        73,0,255, 37,0,255};
79const float cosinus[8][6]={{-0.07,0.12,-0.06,32,25,37},{0.08,-0.03,0.05,51,46,32},{0.12,0.07,-0.13,27,45,36},
80        {0.05,-0.04,-0.07,36,27,39},{-0.02,-0.07,0.1,21,43,42},{-0.11,0.06,0.02,51,25,34},{0.04,-0.15,0.02,42,32,25},
81        {-0.02,-0.04,-0.13,34,20,15}};
82
83static float acosinus[8][3]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
84static int coords[8];
85static int ocoords[8]={0,0,0,0,0,0,0,0};
86
87static Display *dpy;
88static Window win[2];
89static GC fgc[33];
90static GC cgc;
91static int sizx,sizy;
92static int midx,midy;
93static unsigned long delay;
94static Bool cosilines=True;
95#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
96static Bool usedouble=False;
97#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
98
99static int *Xrotations;
100static int *Yrotations;
101static int *Xrottable;
102static int *Yrottable;
103
104static int *rotateX;
105static int *rotateY;
106
107static int rotsizeX,rotsizeY;
108static int stateX,stateY;
109
110static int rx,ry;
111
112
113int Satnum(int maxi)
114{
115return (int)(maxi*frand(1));
116}
117
118
119void palaRotate(int x,int y)
120{
121int ax,ay,bx,by,cx,cy;
122
123ax=rotateX[x];
124ay=rotateY[y];
125bx=rotateX[x+1]+2;
126by=rotateY[y+1]+2;
127cx=rotateX[x]-(y-ry)+x-rx;
128cy=rotateY[y]+(x-rx)+y-ry;
129if (cx<0)
130        {
131        ax-=cx;
132        cx=0;
133        }
134if (cy<0)
135        {
136        ay-=cy;
137        cy=0;
138        }
139if (cx+bx-ax>sizx) bx=ax-cx+sizx;
140if (cy+by-ay>sizy) by=ay-cy+sizy;
141if (ax<bx && ay<by)
142        XCopyArea(dpy,win[0],win[1],cgc,ax,ay,bx-ax,by-ay,cx,cy);
143}
144
145
146void rotate(void)
147{
148int x,y;
149int dx,dy;
150
151rx=Xrottable[stateX+1]-Xrottable[stateX];
152ry=Yrottable[stateY+1]-Yrottable[stateY];
153
154
155for (x=0;x<=rx;x++)
156        rotateX[x]=(x)?midx-1-Xrotations[Xrottable[stateX+1]-x]:0;
157for (x=0;x<=rx;x++)
158        rotateX[x+rx+1]=(x==rx)?sizx-1:midx+Xrotations[Xrottable[stateX]+x];
159for (y=0;y<=ry;y++)
160        rotateY[y]=(y)?midy-1-Yrotations[Yrottable[stateY+1]-y]:0;
161for (y=0;y<=ry;y++)
162        rotateY[y+ry+1]=(y==ry)?sizy-1:midy+Yrotations[Yrottable[stateY]+y];
163
164x=(rx>ry)?rx:ry;
165for (dy=0;dy<(x+1)<<1;dy++)
166        for (dx=0;dx<(x+1)<<1;dx++)
167                {
168                y=(rx>ry)?ry-rx:0;
169                if (dy+y>=0 && dy<(ry+1)<<1 && dx<(rx+1)<<1)
170                        if (dy+y+dx<=ry+rx && dy+y-dx<=ry-rx)
171                                {
172                                palaRotate((rx<<1)+1-dx,dy+y);
173                                palaRotate(dx,(ry<<1)+1-dy-y);
174                                }
175                y=(ry>rx)?rx-ry:0;
176                if (dy+y>=0 && dx<(ry+1)<<1 && dy<(rx+1)<<1)
177                        if (dy+y+dx<=ry+rx && dx-dy-y>=ry-rx)
178                                {
179                                palaRotate(dy+y,dx);
180                                palaRotate((rx<<1)+1-dy-y,(ry<<1)+1-dx);
181                                }
182                }
183stateX++;
184if (stateX==rotsizeX) stateX=0;
185stateY++;
186if (stateY==rotsizeY) stateY=0;
187}
188
189
190
191Bool make_rots(double xspeed,double yspeed)
192{
193int a,b,c,f,g,j,k=0,l;
194double m,om,ok;
195double d,ix,iy;
196int maxi;
197
198Bool *chks;
199
200rotsizeX=(int)(2/xspeed+1);
201ix=(double)(midx+1)/(double)(rotsizeX);
202rotsizeY=(int)(2/yspeed+1);
203iy=(double)(midy+1)/(double)(rotsizeY);
204
205Xrotations=malloc((midx+2)*sizeof(unsigned int));
206Xrottable=malloc((rotsizeX+1)*sizeof(unsigned int));
207Yrotations=malloc((midy+2)*sizeof(unsigned int));
208Yrottable=malloc((rotsizeY+1)*sizeof(unsigned int));
209chks=malloc(((midx>midy)?midx:midy)*sizeof(Bool));
210if (!Xrottable || !Yrottable || !Xrotations || !Yrotations || !chks) return False;
211
212
213maxi=0;
214c=0;
215d=0;
216g=0;
217for (a=0;a<midx;a++) chks[a]=True;
218for (a=0;a<rotsizeX;a++)
219        {
220        Xrottable[a]=c;
221        f=(int)(d+ix)-g;                                /*viivojen lkm.*/
222        g+=f;
223        if (g>midx)
224                {
225                f-=g-midx;
226                g=midx;
227                }
228        for (b=0;b<f;b++)
229                {
230                m=0;
231                for (j=0;j<midx;j++)                    /*testi*/
232                        {
233                        if (chks[j])
234                                {
235                                om=0;
236                                ok=1;
237                                l=0;
238                                while (j+l<midx && om+12*ok>m)
239                                        {
240                                        if (j-l>=0) if (chks[j-l]) om+=ok;
241                                                else; else if (chks[l-j]) om+=ok;
242                                        if (chks[j+l]) om+=ok;
243                                        ok/=1.5;
244                                        l++;
245                                        }
246                                if (om>=m)
247                                        {
248                                        k=j;
249                                        m=om;
250                                        }
251                                }
252                        }
253                chks[k]=False;
254                l=c;
255                while (l>=Xrottable[a])
256                        {
257                        if (l!=Xrottable[a]) Xrotations[l]=Xrotations[l-1];
258                        if (k>Xrotations[l] || l==Xrottable[a])
259                                {
260                                Xrotations[l]=k;
261                                c++;
262                                l=Xrottable[a];
263                                }
264                        l--;
265                        }
266                }
267        d+=ix;
268        if (maxi<c-Xrottable[a]) maxi=c-Xrottable[a];
269        }
270Xrottable[a]=c;
271rotateX=malloc((maxi+2)*sizeof(int)<<1);
272if (!rotateX) return False;
273
274maxi=0;
275c=0;
276d=0;
277g=0;
278for (a=0;a<midy;a++) chks[a]=True;
279for (a=0;a<rotsizeY;a++)
280        {
281        Yrottable[a]=c;
282        f=(int)(d+iy)-g;                                /*viivojen lkm.*/
283        g+=f;
284        if (g>midy)
285                {
286                f-=g-midy;
287                g=midy;
288                }
289        for (b=0;b<f;b++)
290                {
291                m=0;
292                for (j=0;j<midy;j++)                    /*testi*/
293                        {
294                        if (chks[j])
295                                {
296                                om=0;
297                                ok=1;
298                                l=0;
299                                while (j+l<midy && om+12*ok>m)
300                                        {
301                                        if (j-l>=0) if (chks[j-l]) om+=ok;
302                                                else; else if (chks[l-j]) om+=ok;
303                                        if (chks[j+l]) om+=ok;
304                                        ok/=1.5;
305                                        l++;
306                                        }
307                                if (om>=m)
308                                        {
309                                        k=j;
310                                        m=om;
311                                        }
312                                }
313                        }
314                chks[k]=False;
315                l=c;
316                while (l>=Yrottable[a])
317                        {
318                        if (l!=Yrottable[a]) Yrotations[l]=Yrotations[l-1];
319                        if (k>Yrotations[l] || l==Yrottable[a])
320                                {
321                                Yrotations[l]=k;
322                                c++;
323                                l=Yrottable[a];
324                                }
325                        l--;
326                        }
327
328                }
329        d+=iy;
330        if (maxi<c-Yrottable[a]) maxi=c-Yrottable[a];
331        }
332Yrottable[a]=c;
333rotateY=malloc((maxi+2)*sizeof(int)<<1);
334if (!rotateY) return False;
335
336free(chks);
337return (True);
338}
339
340
341Bool InitializeAll(void)
342{
343XGCValues xgcv;
344XWindowAttributes xgwa;
345XSetWindowAttributes xswa;
346Colormap cmap;
347XColor color;
348int n,i;
349double rspeed;
350
351XGetWindowAttributes(dpy,win[0],&xgwa);
352cmap=xgwa.colormap;
353xswa.backing_store=Always;
354XChangeWindowAttributes(dpy,win[0],CWBackingStore,&xswa);
355xgcv.function=GXcopy;
356
357xgcv.foreground=get_pixel_resource ("background", "Background", dpy, cmap);
358fgc[32]=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
359
360n=0;
361if (mono_p)
362        {
363        fgc[0]=fgc[32];
364        xgcv.foreground=get_pixel_resource ("foreground", "Foreground", dpy, cmap);
365        fgc[1]=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
366        for (i=0;i<32;i+=2) fgc[i]=fgc[0];
367        for (i=1;i<32;i+=2) fgc[i]=fgc[1];
368        } else
369        for (i=0;i<32;i++)
370        {
371                color.red=colors[n++]<<8;
372                color.green=colors[n++]<<8;
373                color.blue=colors[n++]<<8;
374                color.flags=DoRed|DoGreen|DoBlue;
375                XAllocColor(dpy,cmap,&color);
376                xgcv.foreground=color.pixel;
377                fgc[i]=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
378        }
379cgc=XCreateGC(dpy,win[0],GCForeground|GCFunction,&xgcv);
380XSetGraphicsExposures(dpy,cgc,False);
381
382if (get_string_resource("random","String")!=NULL && get_string_resource("random","String")[0]!=0) cosilines=False;
383
384#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
385 usedouble = True;
386 win[1] = xdbe_get_backbuffer (dpy, win[0], XdbeUndefined);
387 if (!win[1])
388   {
389     usedouble = False;
390     win[1] = win[0];
391   }
392#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
393
394delay=get_integer_resource("delay","Integer");
395rspeed=get_float_resource("speed","Float");
396if (rspeed<0.0001 || rspeed>0.2)
397        {
398        fprintf(stderr,"Speed not in valid range! (0.0001 - 0.2), using 0.1 \n");
399        rspeed=0.1;
400        }
401
402sizx=xgwa.width;
403sizy=xgwa.height;
404midx=sizx>>1;
405midy=sizy>>1;
406stateX=0;
407stateY=0;
408
409if (!make_rots(rspeed,rspeed))
410        {
411        fprintf(stderr,"Not enough memory for tables!\n");
412        return False;
413        }
414return True;
415}
416
417
418void screenhack(Display *d, Window w)
419{
420#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
421XdbeSwapInfo xdswp;
422#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
423int a,b,c=0,e;
424float f;
425
426dpy=d;
427win[0]=w;
428if (!InitializeAll()) return;
429
430#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
431if (usedouble)
432        {
433        xdswp.swap_action=XdbeUndefined;
434        xdswp.swap_window=win[0];
435        }
436 else
437#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
438   win[1]=win[0];
439
440while (0==0)
441        {
442        if (cosilines)
443                {
444                c++;
445                for (a=0;a<8;a++)
446                        {
447                        f=0;
448                        for (b=0;b<3;b++)
449                                {
450                                acosinus[a][b]+=cosinus[a][b];
451                                f+=cosinus[a][b+3]*sin((double)acosinus[a][b]);
452                                }
453                        coords[a]=(int)f;
454                        }
455                for (a=0;a<4;a++)
456                        {
457                        XDrawLine(dpy,win[0],(mono_p)?fgc[1]:fgc[((a<<2)+c)&31],midx+ocoords[a<<1],midy+ocoords[(a<<1)+1]
458                        ,midx+coords[a<<1],midy+coords[(a<<1)+1]);
459                        ocoords[a<<1]=coords[a<<1];
460                        ocoords[(a<<1)+1]=coords[(a<<1)+1];
461                        }
462
463                } else {
464                for (e=0;e<8;e++)
465                        {
466                        a=Satnum(50);
467                        if (a>=32) a=32;
468                        b=Satnum(32)-16+midx;
469                        c=Satnum(32)-16+midy;
470                        XFillRectangle(dpy,win[0],fgc[a],b,c,2,2);
471                        }
472                }
473        XFillRectangle(dpy,win[0],fgc[32],midx-2,midy-2,4,4);
474        rotate();
475#ifdef HAVE_DOUBLE_BUFFER_EXTENSION
476        if (usedouble) XdbeSwapBuffers(dpy,&xdswp,1);
477#endif /* HAVE_DOUBLE_BUFFER_EXTENSION */
478        XSync(dpy, False);
479        screenhack_handle_events (dpy);
480        if (delay) usleep (delay);
481        }
482}
Note: See TracBrowser for help on using the repository browser.