1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* sphere --- a bunch of shaded spheres */
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)sphere.c 5.00 2000/11/01 xlockmore";
10 * Copyright (c) 1988 by Sun Microsystems
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.
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.
25 * 01-Nov-2000: Allocation checks
26 * 30-May-1997: <jwz@jwz.org> made it go vertically as well as horizontally.
27 * 27-May-1997: <jwz@jwz.org> turned into a standalone program.
28 * 02-Sep-1993: xlock version David Bagley <bagleyd@tux.org>
29 * 1988: Revised to use SunView canvas instead of gfxsw Sun Microsystems
30 * 1982: Orignal Algorithm Tom Duff Lucasfilm Ltd.
35 * **************************************************************************
36 * Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA.
40 * Permission to use, copy, modify, and distribute this software and its
41 * documentation for any purpose and without fee is hereby granted, provided
42 * that the above copyright notice appear in all copies and that both that
43 * copyright notice and this permission notice appear in supporting
44 * documentation, and that the names of Sun or MIT not be used in advertising
45 * or publicity pertaining to distribution of the software without specific
46 * prior written permission. Sun and M.I.T. make no representations about the
47 * suitability of this software for any purpose. It is provided "as is"
48 * without any express or implied warranty.
50 * SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
52 * IN NO EVENT SHALL SUN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
53 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
54 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
55 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
57 * ***************************************************************************
62 #define PROGCLASS "Sphere"
63 #define HACK_INIT init_sphere
64 #define HACK_DRAW draw_sphere
65 #define sphere_opts xlockmore_opts
66 #define DEFAULTS "*delay: 1000 \n" \
71 #include "xlockmore.h" /* from the xscreensaver distribution */
72 #else /* !STANDALONE */
73 #include "xlock.h" /* from the xlockmore distribution */
74 #endif /* !STANDALONE */
78 ModeSpecOpt sphere_opts =
79 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
82 ModStruct sphere_description =
83 {"sphere", "init_sphere", "draw_sphere", "release_sphere",
84 "refresh_sphere", "init_sphere", (char *) NULL, &sphere_opts,
85 5000, 1, 20, 0, 64, 1.0, "",
86 "Shows a bunch of shaded spheres", 0, NULL};
91 * (NX, NY, NZ) is the light source vector -- length should be 100
97 #define SQRT(a) ((int)sqrt((double)(a)))
102 int x0; /* x center */
103 int y0; /* y center */
107 int shadowx, shadowy;
112 static spherestruct *spheres = (spherestruct *) NULL;
115 init_sphere(ModeInfo * mi)
119 if (spheres == NULL) {
120 if ((spheres = (spherestruct *) calloc(MI_NUM_SCREENS(mi),
121 sizeof (spherestruct))) == NULL)
124 sp = &spheres[MI_SCREEN(mi)];
126 if (sp->points != NULL) {
127 (void) free((void *) sp->points);
128 sp->points = (XPoint *) NULL;
130 sp->width = MAX(MI_WIDTH(mi), 4);
131 sp->height = MAX(MI_HEIGHT(mi), 4);
132 if ((sp->points = (XPoint *) malloc(MIN(sp->width, sp->height) *
133 sizeof (XPoint))) == NULL) {
141 sp->shadowx = (LRAND() & 1) ? 1 : -1;
142 sp->shadowy = (LRAND() & 1) ? 1 : -1;
146 draw_sphere(ModeInfo * mi)
148 Display *display = MI_DISPLAY(mi);
151 register int minx = 0, maxx = 0, miny = 0, maxy = 0, npts = 0;
156 sp = &spheres[MI_SCREEN(mi)];
157 if (sp->points == NULL)
160 MI_IS_DRAWN(mi) = True;
161 if ((sp->dirx && ABS(sp->x) >= sp->radius) ||
162 (sp->diry && ABS(sp->y) >= sp->radius)) {
163 sp->radius = NRAND(MIN(sp->width / 2, sp->height / 2) - 1) + 1;
166 sp->dirx = (int) (LRAND() & 1) * 2 - 1;
170 sp->diry = (int) (LRAND() & 1) * 2 - 1;
172 sp->x0 = NRAND(sp->width);
173 sp->y0 = NRAND(sp->height);
175 sp->x = -sp->radius * sp->dirx;
176 sp->y = -sp->radius * sp->diry;
178 if (MI_NPIXELS(mi) > 2)
179 sp->color = NRAND(MI_NPIXELS(mi));
182 if (sp->x0 + sp->x < 0)
184 } else if (sp->dirx == -1) {
185 if (sp->x0 + sp->x >= sp->width)
186 sp->x = sp->width - sp->x0 - 1;
189 if (sp->y0 + sp->y < 0)
191 } else if (sp->diry == -1) {
192 if (sp->y0 + sp->y >= sp->height)
193 sp->y = sp->height - sp->y0 - 1;
196 sp->maxy = SQRT(sp->radius * sp->radius - sp->x * sp->x);
198 if (sp->y0 - sp->maxy < 0)
203 sp->maxx = SQRT(sp->radius * sp->radius - sp->y * sp->y);
205 if (sp->x0 - sp->maxx < 0)
210 if (sp->y0 + sp->maxy >= sp->height)
211 maxy = sp->height - sp->y0;
214 if (sp->x0 + sp->maxx >= sp->width)
215 maxx = sp->width - sp->x0;
217 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
220 XDrawLine(display, MI_WINDOW(mi), gc,
221 sp->x0 + sp->x, sp->y0 + miny, sp->x0 + sp->x, sp->y0 + maxy);
223 XDrawLine(display, MI_WINDOW(mi), gc,
224 sp->x0 + minx, sp->y0 + sp->y, sp->x0 + maxx, sp->y0 + sp->y);
226 if (MI_NPIXELS(mi) > 2)
227 XSetForeground(display, gc, MI_PIXEL(mi, sp->color));
229 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
232 sqrd = sp->radius * sp->radius - sp->x * sp->x;
233 nd = NX * sp->shadowx * sp->x;
234 for (sp->y = miny; sp->y <= maxy; sp->y++)
235 if ((NRAND(sp->radius * NR)) <= nd + NY * sp->shadowy * sp->y +
236 NZ * SQRT(sqrd - sp->y * sp->y)) {
237 sp->points[npts].x = sp->x + sp->x0;
238 sp->points[npts].y = sp->y + sp->y0;
243 sqrd = sp->radius * sp->radius - sp->y * sp->y;
244 nd = NY * sp->shadowy * sp->y;
245 for (sp->x = minx; sp->x <= maxx; sp->x++)
246 if ((NRAND(sp->radius * NR)) <= NX * sp->shadowx * sp->x + nd +
247 NZ * SQRT(sqrd - sp->x * sp->x)) {
248 sp->points[npts].x = sp->x + sp->x0;
249 sp->points[npts].y = sp->y + sp->y0;
253 XDrawPoints(display, MI_WINDOW(mi), gc, sp->points, npts, CoordModeOrigin);
256 if (sp->x0 + sp->x >= sp->width)
258 } else if (sp->dirx == -1) {
260 if (sp->x0 + sp->x < 0)
265 if (sp->y0 + sp->y >= sp->height)
267 } else if (sp->diry == -1) {
269 if (sp->y0 + sp->y < 0)
275 release_sphere(ModeInfo * mi)
277 if (spheres != NULL) {
280 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
281 spherestruct *sp = &spheres[screen];
284 (void) free((void *) sp->points);
285 /* sp->points = NULL; */
288 (void) free((void *) spheres);
289 spheres = (spherestruct *) NULL;
294 refresh_sphere(ModeInfo * mi)
300 sp = &spheres[MI_SCREEN(mi)];
307 #endif /* MODE_sphere */