+++ /dev/null
-/* -*- Mode: C; tab-width: 4 -*-
- * sphere.c --- draw a bunch of shaded spheres
- */
-#if !defined( lint ) && !defined( SABER )
-static const char sccsid[] = "@(#)sphere.c 4.00 97/01/01 xlockmore";
-#endif
-
-/* Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA.
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the names of Sun or MIT not be used in advertising
- * or publicity pertaining to distribution of the software without specific
- * prior written permission. Sun and M.I.T. make no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without any express or implied warranty.
- *
- * SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- * IN NO EVENT SHALL SUN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * ***************************************************************************
- *
- * Revision History:
- * 30-May-97: jwz@jwz.org: made it go vertically as well as horizontally.
- * 27-May-97: jwz@jwz.org: turned into a standalone program.
- * 2-Sep-93: xlock version (David Bagley bagleyd@bigfoot.com)
- * 1988: Revised to use SunView canvas instead of gfxsw Sun Microsystems
- * 1982: Orignal Algorithm Tom Duff Lucasfilm Ltd.
- */
-
-#ifdef STANDALONE
-# define PROGCLASS "Sphere"
-# define HACK_INIT init_sphere
-# define HACK_DRAW draw_sphere
-# define sphere_opts xlockmore_opts
-# define DEFAULTS "*delay: 1000 \n" \
- "*ncolors: 64 \n"
-# define BRIGHT_COLORS
-# include "xlockmore.h" /* from the xscreensaver distribution */
-#else /* !STANDALONE */
-# include "xlock.h" /* from the xlockmore distribution */
-#endif /* !STANDALONE */
-
-ModeSpecOpt sphere_opts = {
- 0, NULL, 0, NULL, NULL };
-
-/*-
- * (NX, NY, NZ) is the light source vector -- length should be 100
- */
-#define NX 48
-#define NY (-36)
-#define NZ 80
-#define NR 100
-#define SQRT(a) ((int)sqrt((double)(a)))
-
-typedef struct {
- int width, height;
- int radius;
- int x0; /* x center */
- int y0; /* y center */
- int color;
- int x, y;
- int dirx, diry;
- int maxx, maxy;
- XPoint *points;
-} spherestruct;
-
-static spherestruct *spheres = NULL;
-
-void
-init_sphere(ModeInfo * mi)
-{
- spherestruct *sp;
-
- if (spheres == NULL) {
- if ((spheres = (spherestruct *) calloc(MI_NUM_SCREENS(mi),
- sizeof (spherestruct))) == NULL)
- return;
- }
- sp = &spheres[MI_SCREEN(mi)];
-
- if (sp->points) {
- (void) free((void *) sp->points);
- sp->points = NULL;
- }
- sp->width = MI_WIN_WIDTH(mi);
- sp->height = MI_WIN_HEIGHT(mi);
- sp->points = (XPoint *) malloc(sp->height * sizeof (XPoint));
-
- XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
-
- sp->dirx = 1;
-}
-
-void
-draw_sphere(ModeInfo * mi)
-{
- Display *display = MI_DISPLAY(mi);
- GC gc = MI_GC(mi);
- spherestruct *sp = &spheres[MI_SCREEN(mi)];
- int minx = 0, maxx = 0, miny = 0, maxy = 0, npts = 0;
-
- if ((sp->dirx && ABS(sp->x) >= sp->radius) ||
- (sp->diry && ABS(sp->y) >= sp->radius)) {
- sp->radius = NRAND(MIN(sp->width / 2, sp->height / 2) - 1) + 1;
-
- if (LRAND() & 1) {
- sp->dirx = (LRAND() & 1) * 2 - 1;
- sp->diry = 0;
- } else {
- sp->dirx = 0;
- sp->diry = (LRAND() & 1) * 2 - 1;
- }
- sp->x0 = NRAND(sp->width);
- sp->y0 = NRAND(sp->height);
-
- sp->x = -sp->radius * sp->dirx;
- sp->y = -sp->radius * sp->diry;
-
- if (MI_NPIXELS(mi) > 2)
- sp->color = NRAND(MI_NPIXELS(mi));
- }
- if (sp->dirx == 1) {
- if (sp->x0 + sp->x < 0)
- sp->x = -sp->x0;
- } else if (sp->dirx == -1) {
- if (sp->x0 + sp->x >= sp->width)
- sp->x = sp->width - sp->x0 - 1;
- }
- if (sp->diry == 1) {
- if (sp->y0 + sp->y < 0)
- sp->y = -sp->y0;
- } else if (sp->diry == -1) {
- if (sp->y0 + sp->y >= sp->height)
- sp->y = sp->height - sp->y0 - 1;
- }
- if (sp->dirx) {
- sp->maxy = SQRT(sp->radius * sp->radius - sp->x * sp->x);
- miny = -sp->maxy;
- if (sp->y0 - sp->maxy < 0)
- miny = -sp->y0;
- maxy = sp->maxy;
- }
- if (sp->diry) {
- sp->maxx = SQRT(sp->radius * sp->radius - sp->y * sp->y);
- minx = -sp->maxx;
- if (sp->x0 - sp->maxx < 0)
- minx = -sp->x0;
- maxx = sp->maxx;
- }
- if (sp->dirx) {
- if (sp->y0 + sp->maxy >= sp->height)
- maxy = sp->height - sp->y0;
- }
- if (sp->diry) {
- if (sp->x0 + sp->maxx >= sp->width)
- maxx = sp->width - sp->x0;
- }
- XSetForeground(display, gc, MI_WIN_BLACK_PIXEL(mi));
-
- if (sp->dirx)
- XDrawLine(display, MI_WINDOW(mi), gc,
- sp->x0 + sp->x, sp->y0 + miny, sp->x0 + sp->x, sp->y0 + maxy);
- if (sp->diry)
- XDrawLine(display, MI_WINDOW(mi), gc,
- sp->x0 + minx, sp->y0 + sp->y, sp->x0 + maxx, sp->y0 + sp->y);
-
- if (MI_NPIXELS(mi) > 2)
- XSetForeground(display, gc, MI_PIXEL(mi, sp->color));
- else
- XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
-
- if (sp->dirx)
- for (sp->y = miny; sp->y <= maxy; sp->y++)
- if ((NRAND(sp->radius * NR)) <=
- (NX * sp->x + NY * sp->y + NZ *
- SQRT(sp->radius * sp->radius - sp->x * sp->x - sp->y * sp->y))) {
- sp->points[npts].x = sp->x + sp->x0;
- sp->points[npts].y = sp->y + sp->y0;
- npts++;
- }
- if (sp->diry)
- for (sp->x = minx; sp->x <= maxx; sp->x++)
- if ((NRAND(sp->radius * NR)) <=
- (NX * sp->x + NY * sp->y + NZ *
- SQRT(sp->radius * sp->radius - sp->x * sp->x - sp->y * sp->y))) {
- sp->points[npts].x = sp->x + sp->x0;
- sp->points[npts].y = sp->y + sp->y0;
- npts++;
- }
- XDrawPoints(display, MI_WINDOW(mi), gc, sp->points, npts, CoordModeOrigin);
- if (sp->dirx == 1) {
- sp->x++;
- if (sp->x0 + sp->x >= sp->width)
- sp->x = sp->radius;
- } else if (sp->dirx == -1) {
- sp->x--;
- if (sp->x0 + sp->x < 0)
- sp->x = -sp->radius;
- }
- if (sp->diry == 1) {
- sp->y++;
- if (sp->y0 + sp->y >= sp->height)
- sp->y = sp->radius;
- } else if (sp->diry == -1) {
- sp->y--;
- if (sp->y0 + sp->y < 0)
- sp->y = -sp->radius;
- }
-}
-
-void
-release_sphere(ModeInfo * mi)
-{
- if (spheres != NULL) {
- int screen;
-
- for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
- spherestruct *sp = &spheres[screen];
-
- if (sp->points) {
- (void) free((void *) sp->points);
- sp->points = NULL;
- }
- }
- (void) free((void *) spheres);
- spheres = NULL;
- }
-}
-
-void
-refresh_sphere(ModeInfo * mi)
-{
- spherestruct *sp = &spheres[MI_SCREEN(mi)];
-
- XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
- sp->x = -sp->radius;
-}