ftp://ftp.sunet.se/pub/os/Linux/distributions/ultrapenguin/ultrapenguin-1.1/SRPMS...
[xscreensaver] / hacks / fract.c
1 /* -*- Mode: C; tab-width: 4 -*-
2  * fract --- another geometric pattern generator.
3  */
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)fract.c       4.02 97/04/01 xlockmore";
6 #endif
7
8 /* xlockmore mode written by Tracy Camp
9  * campt@hurrah.com 1997
10  * released to the public domain
11  *
12  * This was modifed from a 'screen saver' that a friend and I
13  * wrote on our TI-8x calculators in high school physics one day
14  * Basically another geometric pattern generator, this ones claim
15  * to fame is a pseudo-fractal looking vine like pattern that creates
16  * nifty whorls and loops.
17  *
18  * Revision History:
19  * 10-May-97: jwz@netscape.com: turned into a standalone program.
20  * 21-Mar-97:  David Hansen <dhansen@metapath.com>
21  *             Updated mode to draw complete patterns on every
22  *             iteration instead of growing the vine.  Also made
23  *             adjustments to randomization and changed variable
24  *             names to make logic easier to follow.
25  */
26
27 #ifdef STANDALONE
28 # define PROGCLASS                                      "Fract"
29 # define HACK_INIT                                      init_fract
30 # define HACK_DRAW                                      draw_fract
31 # define fract_opts                                     xlockmore_opts
32 # define DEFAULTS               "*delay:        200000 \n"      \
33                                                 "*ncolors:      64     \n"
34 # include "xlockmore.h"                         /* from the xscreensaver distribution */
35 #else  /* !STANDALONE */
36 # include "xlock.h"                                     /* from the xlockmore distribution */
37 #endif /* !STANDALONE */
38
39 ModeSpecOpt fract_opts = {
40   0, NULL, 0, NULL, NULL };
41
42 typedef struct {
43         int         a;
44         int         x1;
45         int         y1;
46         int         x2;
47         int         y2;
48         int         length;
49         int         iterations;
50         int         constant;
51         int         ang;
52         int         centerx;
53         int         centery;
54 } fractstruct;
55
56 static fractstruct *fracts = NULL;
57
58 void
59 refresh_fract(ModeInfo * mi)
60 {
61 }
62
63 void
64 init_fract(ModeInfo * mi)
65 {
66         Display    *display = MI_DISPLAY(mi);
67         fractstruct *fp;
68
69         if (fracts == NULL) {
70                 if ((fracts = (fractstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (fractstruct))) == NULL) {
71                         return;
72                 }
73         }
74         fp = &fracts[MI_SCREEN(mi)];
75
76         fp->iterations = 30 + NRAND(100);
77
78         XClearWindow(display, MI_WINDOW(mi));
79 }
80
81 void
82 draw_fract(ModeInfo * mi)
83 {
84         fractstruct *fp = &fracts[MI_SCREEN(mi)];
85         Display    *display = MI_DISPLAY(mi);
86         GC          gc = MI_GC(mi);
87         int         i;
88
89         if (--(fp->iterations) == 0)
90                 init_fract(mi);
91
92         fp->centerx = NRAND(MI_WIN_WIDTH(mi));
93         fp->centery = NRAND(MI_WIN_HEIGHT(mi));
94
95         fp->ang = 60 + NRAND(720);
96         fp->length = 100 + NRAND(3000);
97         fp->constant = fp->length * (10 + NRAND(10));
98
99         fp->a = 0;
100         fp->x1 = 0;
101         fp->y1 = 0;
102         fp->x2 = 1;
103         fp->y2 = 0;
104
105         if (MI_NPIXELS(mi) > 2)
106                 XSetForeground(display, gc, MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))));
107         else
108                 XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
109
110
111         for (i = 0; i < fp->length; i++) {
112                 XDrawLine(display, MI_WINDOW(mi), gc,
113                           fp->centerx + (fp->x1 / fp->constant),
114                           fp->centery - (fp->y1 / fp->constant),
115                           fp->centerx + (fp->x2 / fp->constant),
116                           fp->centery - (fp->y2 / fp->constant));
117
118                 fp->a += (fp->ang * i);
119
120                 fp->x1 = fp->x2;
121                 fp->y1 = fp->y2;
122
123                 fp->x2 += (int) (i * ((cos(fp->a) * 360) / (2 * M_PI)));
124                 fp->y2 += (int) (i * ((sin(fp->a) * 360) / (2 * M_PI)));
125         }
126 }
127
128 void
129 release_fract(ModeInfo * mi)
130 {
131         if (fracts != NULL) {
132                 (void) free((void *) fracts);
133                 fracts = NULL;
134         }
135 }