http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / vines.c
1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* vines --- vine fractals */
3
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)vines.c       5.00 2000/11/01 xlockmore";
6
7 #endif
8
9 /*-
10  * Copyright (c) 1997 by Tracy Camp campt@hurrah.com
11  *
12  * Permission to use, copy, modify, and distribute this software and its
13  * documentation for any purpose and without fee is hereby granted,
14  * provided that the above copyright notice appear in all copies and that
15  * both that copyright notice and this permission notice appear in
16  * supporting documentation.
17  *
18  * This file is provided AS IS with no warranties of any kind.  The author
19  * shall have no liability with respect to the infringement of copyrights,
20  * trade secrets or any patents by this file or any part thereof.  In no
21  * event will the author be liable for any lost revenue or profits or
22  * other special, indirect and consequential damages.
23  *
24  * If you make a modification I would of course appreciate a copy.
25  *
26  * Revision History:
27  * 01-Nov-2000: Allocation checks
28  * 11-Jul-1997: David Hansen <dhansen@metapath.com>
29  *              Changed names to vines and modified draw loop
30  *              to honor batchcount so vines can be grown or plotted.
31  * 10-May-1997: Compatible with xscreensaver
32  * 21-Mar-1997: David Hansen <dhansen@metapath.com>
33  *              Updated mode to draw complete patterns on every
34  *              iteration instead of growing the vine.  Also made
35  *              adjustments to randomization and changed variable
36  *              names to make logic easier to follow.
37  */
38
39 /*-
40  * This was modifed from a 'screen saver' that a friend and I
41  * wrote on our TI-8x calculators in high school physics one day
42  * Basically another geometric pattern generator, this ones claim
43  * to fame is a pseudo-fractal looking vine like pattern that creates
44  * nifty whorls and loops.
45  */
46
47 #ifdef STANDALONE
48 #define MODE_vines
49 #define PROGCLASS "Vines"
50 #define HACK_INIT init_vines
51 #define HACK_DRAW draw_vines
52 #define vines_opts xlockmore_opts
53 #define DEFAULTS "*delay: 200000 \n" \
54  "*count: 0 \n" \
55  "*ncolors: 64 \n"
56 #include "xlockmore.h"          /* in xscreensaver distribution */
57 #include "erase.h"
58 #else /* STANDALONE */
59 #include "xlock.h"              /* in xlockmore distribution */
60 #endif /* STANDALONE */
61
62 #ifdef MODE_vines
63
64 ModeSpecOpt vines_opts =
65 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
66
67 #ifdef USE_MODULES
68 ModStruct   vines_description =
69 {"vines", "init_vines", "draw_vines", "release_vines",
70  "refresh_vines", "init_vines", (char *) NULL, &vines_opts,
71  200000, 0, 1, 1, 64, 1.0, "",
72  "Shows fractals", 0, NULL};
73
74 #endif
75
76 typedef struct {
77         int         a;
78         int         x1;
79         int         y1;
80         int         x2;
81         int         y2;
82         int         i;
83         int         length;
84         int         iterations;
85         int         constant;
86         int         ang;
87         int         centerx;
88         int         centery;
89 } vinestruct;
90
91 static vinestruct *vines = (vinestruct *) NULL;
92
93 void
94 refresh_vines(ModeInfo * mi)
95 {
96         MI_CLEARWINDOW(mi);
97 }                               /* refresh_vines */
98
99 void
100 init_vines(ModeInfo * mi)
101 {
102         vinestruct *fp;
103
104         if (vines == NULL) {
105                 if ((vines = (vinestruct *) calloc(MI_NUM_SCREENS(mi),
106                                              sizeof (vinestruct))) == NULL) {
107                         return;
108                 }
109         }
110         fp = &vines[MI_SCREEN(mi)];
111
112         fp->i = 0;
113         fp->length = 0;
114         fp->iterations = 30 + NRAND(100);
115
116         MI_CLEARWINDOW(mi);
117 }                               /* init_vines */
118
119 void
120 draw_vines(ModeInfo * mi)
121 {
122         Display    *display = MI_DISPLAY(mi);
123         GC          gc = MI_GC(mi);
124         int         count;
125         vinestruct *fp;
126
127         if (vines == NULL)
128                 return;
129         fp = &vines[MI_SCREEN(mi)];
130
131         /* MI_IS_DRAWN(mi) = True; */
132         if (fp->i >= fp->length) {
133                 if (--(fp->iterations) == 0) {
134 #ifdef STANDALONE
135           erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
136 #endif /* STANDALONE */
137                         init_vines(mi);
138                 }
139                 fp->centerx = NRAND(MI_WIDTH(mi));
140                 fp->centery = NRAND(MI_HEIGHT(mi));
141
142                 fp->ang = 60 + NRAND(720);
143                 fp->length = 100 + NRAND(3000);
144                 fp->constant = fp->length * (10 + NRAND(10));
145
146                 fp->i = 0;
147                 fp->a = 0;
148                 fp->x1 = 0;
149                 fp->y1 = 0;
150                 fp->x2 = 1;
151                 fp->y2 = 0;
152
153                 if (MI_NPIXELS(mi) > 2)
154                         XSetForeground(display, gc, MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))));
155                 else
156                         XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
157         }
158         count = fp->i + MI_COUNT(mi);
159         if ((count <= fp->i) || (count > fp->length))
160                 count = fp->length;
161
162         while (fp->i < count) {
163                 XDrawLine(display, MI_WINDOW(mi), gc,
164                           fp->centerx + (fp->x1 / fp->constant),
165                           fp->centery - (fp->y1 / fp->constant),
166                           fp->centerx + (fp->x2 / fp->constant),
167                           fp->centery - (fp->y2 / fp->constant));
168
169                 fp->a += (fp->ang * fp->i);
170
171                 fp->x1 = fp->x2;
172                 fp->y1 = fp->y2;
173
174                 fp->x2 += (int) (fp->i * (cos((double) fp->a) * 360.0) / (2.0 * M_PI));
175                 fp->y2 += (int) (fp->i * (sin((double) fp->a) * 360.0) / (2.0 * M_PI));
176                 fp->i++;
177         }
178 }                               /* draw_vines */
179
180 void
181 release_vines(ModeInfo * mi)
182 {
183         if (vines != NULL) {
184                 (void) free((void *) vines);
185                 vines = (vinestruct *) NULL;
186         }
187 }                               /* release_vines */
188
189 #endif /* MODE_vines */