X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Flisa.c;h=63d7d8371077331a85466ff9bc132eb4c0625c18;hp=af680ea2057e4a3e4ff80c174011fc38943c659a;hb=a94197e76a5dea5cb60542840809d6c20d0abbf3;hpb=8eb2873d7054e705c4e83f22d18c40946a9e2529 diff --git a/hacks/lisa.c b/hacks/lisa.c index af680ea2..63d7d837 100644 --- a/hacks/lisa.c +++ b/hacks/lisa.c @@ -2,10 +2,12 @@ /* lisa --- animated full-loop lisajous figures */ #if !defined( lint ) && !defined( SABER ) -static const char sccsid[] = "@(#)lisa.c 4.04 97/07/28 xlockmore"; +static const char sccsid[] = "@(#)lisa.c 5.00 2000/11/01 xlockmore"; + #endif -/* Copyright (c) 1997 by Caleb Cullen. +/*- + * Copyright (c) 1997 by Caleb Cullen. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, @@ -20,9 +22,10 @@ static const char sccsid[] = "@(#)lisa.c 4.04 97/07/28 xlockmore"; * other special, indirect and consequential damages. * * Revision History: - * 10-May-97: Compatible with xscreensaver + * 01-Nov-2000: Allocation checks + * 10-May-1997: Compatible with xscreensaver * - * The inspiration for this program, Lasp, was written by Adam B. Roach + * The inspiration for this program, Lasp, was written by Adam B. Roach * in 1990, assisted by me, Caleb Cullen. It was written first in C, then * in assembly, and used pre-calculated data tables to graph lisajous * figures on 386 machines and lower. This version bears only superficial @@ -34,46 +37,57 @@ static const char sccsid[] = "@(#)lisa.c 4.04 97/07/28 xlockmore"; */ #ifdef STANDALONE -# define PROGCLASS "Lisa" -# define HACK_INIT init_lisa -# define HACK_DRAW draw_lisa -# define lisa_opts xlockmore_opts -# define DEFAULTS "*delay: 25000 \n" \ - "*count: 1 \n" \ - "*cycles: 256 \n" \ - "*size: -1 \n" \ - "*ncolors: 200 \n" -# define UNIFORM_COLORS -# include "xlockmore.h" /* from the xscreensaver distribution */ - void refresh_lisa(ModeInfo * mi); - void change_lisa(ModeInfo * mi); -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ +#define MODE_lisa +#define PROGCLASS "Lisa" +#define HACK_INIT init_lisa +#define HACK_DRAW draw_lisa +#define lisa_opts xlockmore_opts +#define DEFAULTS "*delay: 25000 \n" \ + "*count: 1 \n" \ + "*cycles: 256 \n" \ + "*size: -1 \n" \ + "*ncolors: 200 \n" +#define UNIFORM_COLORS +#include "xlockmore.h" /* in xscreensaver distribution */ + +#else /* STANDALONE */ +#include "xlock.h" /* in xlockmore distribution */ + +#endif /* STANDALONE */ + +#ifdef MODE_lisa #define DEF_ADDITIVE "True" static Bool additive; -static XrmOptionDescRec lisa_xrm_opts[] = +static XrmOptionDescRec opts[] = { - {"-additive", ".lisa.additive", XrmoptionNoArg, (caddr_t) "True"}, - {"+additive", ".lisa.additive", XrmoptionNoArg, (caddr_t) "False"} + {(char *) "-additive", (char *) ".lisa.additive", XrmoptionNoArg, (caddr_t) "True"}, + {(char *) "+additive", (char *) ".lisa.additive", XrmoptionNoArg, (caddr_t) "False"} }; -static argtype lisa_vars[] = +static argtype vars[] = { - {(caddr_t *) & additive, "additive", "Additive", DEF_ADDITIVE, t_Bool} + {(caddr_t *) & additive, (char *) "additive", (char *) "Additive", (char *) DEF_ADDITIVE, t_Bool} }; -static OptionStruct lisa_vars_desc[] = +static OptionStruct desc[] = { - {"-/+additive", "turn on/off additive functions mode"} + {(char *) "-/+additive", (char *) "turn on/off additive functions mode"} }; ModeSpecOpt lisa_opts = -{2, lisa_xrm_opts, 1, lisa_vars, lisa_vars_desc}; +{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc}; + +#ifdef USE_MODULES +ModStruct lisa_description = +{"lisa", "init_lisa", "draw_lisa", "release_lisa", + "refresh_lisa", "change_lisa", (char *) NULL, &lisa_opts, + 25000, 1, 256, -1, 64, 1.0, "", + "Shows animated lisajous loops", 0, NULL}; +#endif #define DRAWLINES 1 #define TWOLOOPS 1 @@ -82,12 +96,12 @@ ModeSpecOpt lisa_opts = #define LISAMAXFUNCS 2 #define NUMSTDFUNCS 10 #define MAXCYCLES 3 -#define MINLISAS 1 +#define MINLISAS 1 #define lisasetcolor() \ if (MI_NPIXELS(mi) > 2) { \ XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_PIXEL(mi, loop->color)); \ - if (++(loop->color) >= MI_NPIXELS(mi)) { loop->color=0; } \ - } else { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_WHITE_PIXEL(mi)); } + if (++(loop->color) >= (unsigned) MI_NPIXELS(mi)) { loop->color=0; } \ + } else { XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); } #define getRadius(context) \ ((context->width > context->height)?context->height:context->width) * 3 / 8 #define checkRadius(loop, context) \ @@ -105,19 +119,22 @@ typedef struct lisafunc_struct { } lisafuncs; typedef struct lisa_struct { - int radius, color, dx, dy, nsteps, nfuncs, melting; + unsigned long color; + int radius, dx, dy, nsteps, nfuncs, melting; double pistep, phi, theta; XPoint center, *lastpoint; lisafuncs *function[LISAMAXFUNCS]; + int linewidth; } lisas; typedef struct lisacontext_struct { lisas *lisajous; int width, height, nlisajous, loopcount; int maxcycles; + Bool painted; } lisacons; -static lisacons *Lisa = NULL; +static lisacons *Lisa = (lisacons *) NULL; static lisafuncs Function[NUMSTDFUNCS] = { @@ -154,6 +171,20 @@ static lisafuncs Function[NUMSTDFUNCS] = }; static void +free_lisa(lisacons *lc) +{ + while (lc->lisajous) { + int lctr; + + for (lctr = 0; lctr < lc->nlisajous; lctr++) { + (void) free((void *) lc->lisajous[lctr].lastpoint); + } + (void) free((void *) lc->lisajous); + lc->lisajous = (lisas *) NULL; + } +} + +static Bool drawlisa(ModeInfo * mi, lisas * loop) { XPoint *np; @@ -165,7 +196,10 @@ drawlisa(ModeInfo * mi, lisas * loop) double xprod, yprod, xsum, ysum; /* Allocate the np array */ - np = (XPoint *) calloc(loop->nsteps, sizeof (XPoint)); + if ((np = (XPoint *) calloc(loop->nsteps, sizeof (XPoint))) == NULL) { + free_lisa(lc); + return False; + } /* Update the center */ loop->center.x += loop->dx; @@ -204,42 +238,31 @@ drawlisa(ModeInfo * mi, lisas * loop) yprod += sin(lf[fctr]->ycoeff[yctr] * loop->phi); if (loop->melting) { if (fctr) { - xsum += xprod \ - *(double) (loop->nsteps - loop->melting) \ - /(double) loop->nsteps; - ysum += yprod \ - *(double) (loop->nsteps - loop->melting) \ - /(double) loop->nsteps; + xsum += xprod * (double) (loop->nsteps - loop->melting) / + (double) loop->nsteps; + ysum += yprod * (double) (loop->nsteps - loop->melting) / + (double) loop->nsteps; } else { - xsum += xprod \ - *(double) loop->melting \ - /(double) loop->nsteps; - ysum += yprod \ - *(double) loop->melting \ - /(double) loop->nsteps; + xsum += xprod * (double) loop->melting / (double) loop->nsteps; + ysum += yprod * (double) loop->melting / (double) loop->nsteps; } } else { xsum = xprod; ysum = yprod; } if (!fctr) { - xsum = xsum \ - *(double) loop->radius \ - /(double) lf[fctr]->nx; - ysum = ysum \ - *(double) loop->radius \ - /(double) lf[fctr]->ny; + xsum = xsum * (double) loop->radius / (double) lf[fctr]->nx; + ysum = ysum * (double) loop->radius / (double) lf[fctr]->ny; } } else { if (loop->melting) { if (fctr) { - yprod = xprod = (double) loop->radius \ - *(double) (loop->nsteps - loop->melting) \ - /(double) (loop->nsteps); + yprod = xprod = (double) loop->radius * + (double) (loop->nsteps - loop->melting) / + (double) (loop->nsteps); } else { - yprod = xprod = (double) loop->radius \ - *(double) (loop->melting) \ - /(double) (loop->nsteps); + yprod = xprod = (double) loop->radius * + (double) (loop->melting) / (double) (loop->nsteps); } } else { xprod = yprod = (double) loop->radius; @@ -271,40 +294,45 @@ drawlisa(ModeInfo * mi, lisas * loop) for (pctr = 0; pctr < loop->nsteps; pctr++) { #if defined DRAWLINES + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), loop->linewidth, + LineSolid, CapProjecting, JoinMiter); /* erase the last cycle's point */ - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), \ - MI_GC(mi), lp[pctr].x, lp[pctr].y, \ - lp[(pctr + 1) % loop->nsteps].x, \ + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_GC(mi), lp[pctr].x, lp[pctr].y, + lp[(pctr + 1) % loop->nsteps].x, lp[(pctr + 1) % loop->nsteps].y); /* Set the new color */ lisasetcolor(); /* plot this cycle's point */ - XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), \ - MI_GC(mi), np[pctr].x, np[pctr].y, \ - np[(pctr + 1) % loop->nsteps].x, \ + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_GC(mi), np[pctr].x, np[pctr].y, + np[(pctr + 1) % loop->nsteps].x, np[(pctr + 1) % loop->nsteps].y); + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, + LineSolid, CapProjecting, JoinMiter); #else /* erase the last cycle's point */ - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WIN_BLACK_PIXEL(mi)); - XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), \ + XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi)); + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), lp[pctr].x, lp[pctr].y); /* Set the new color */ lisasetcolor(); /* plot this cycle's point */ - XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), \ + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), np[pctr].x, np[pctr].y); #endif } (void) free((void *) lp); loop->lastpoint = np; + return True; } -static void +static Bool initlisa(ModeInfo * mi, lisas * loop) { lisacons *lc = &Lisa[MI_SCREEN(mi)]; @@ -316,7 +344,7 @@ initlisa(ModeInfo * mi, lisas * loop) if (MI_NPIXELS(mi) > 2) { loop->color = 0; } else - loop->color = MI_WIN_WHITE_PIXEL(mi); + loop->color = MI_WHITE_PIXEL(mi); loop->nsteps = MI_CYCLES(mi); if (loop->nsteps == 0) loop->nsteps = 1; @@ -326,7 +354,7 @@ initlisa(ModeInfo * mi, lisas * loop) loop->pistep = 2.0 * M_PI / (double) loop->nsteps; loop->center.x = lc->width / 2; loop->center.y = lc->height / 2; - loop->radius = MI_SIZE(mi); + loop->radius = (int) MI_SIZE(mi); checkRadius(loop, lc); loop->dx = NRAND(XVMAX); loop->dy = NRAND(YVMAX); @@ -334,8 +362,10 @@ initlisa(ModeInfo * mi, lisas * loop) loop->dy++; lf[0] = &Function[lc->loopcount % NUMSTDFUNCS]; if ((lp = loop->lastpoint = (XPoint *) - calloc(loop->nsteps, sizeof (XPoint))) == NULL) - return; + calloc(loop->nsteps, sizeof (XPoint))) == NULL) { + free_lisa(lc); + return False; + } phase = lc->loopcount % loop->nsteps; for (pctr = 0; pctr < loop->nsteps; pctr++) { @@ -364,122 +394,156 @@ initlisa(ModeInfo * mi, lisas * loop) lp[pctr].x = (int) ceil(xsum); lp[pctr].y = (int) ceil(ysum); } +#if defined DRAWLINES + { + loop->linewidth = -8; /* #### make this a resource */ + + if (loop->linewidth == 0) + loop->linewidth = 1; + if (loop->linewidth < 0) + loop->linewidth = NRAND(-loop->linewidth) + 1; + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), loop->linewidth, + LineSolid, CapProjecting, JoinMiter); + } +#endif for (pctr = 0; pctr < loop->nsteps; pctr++) { /* Set the color */ lisasetcolor(); #if defined DRAWLINES - XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), \ - MI_GC(mi), lp[pctr].x, lp[pctr].y, \ - lp[(pctr + 1) % loop->nsteps].x, \ + XDrawLine(MI_DISPLAY(mi), MI_WINDOW(mi), + MI_GC(mi), lp[pctr].x, lp[pctr].y, + lp[(pctr + 1) % loop->nsteps].x, lp[(pctr + 1) % loop->nsteps].y); #else - XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), \ + XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi), lp[pctr].x, lp[pctr].y); #endif } +#if defined DRAWLINES + XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 1, + LineSolid, CapProjecting, JoinMiter); +#endif + return True; +} - { - int line_width = -15; /* #### make this a resource */ - if (line_width == 0) - line_width = -8; - if (line_width < 0) - line_width = NRAND(-line_width)+1; - XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), line_width, - LineSolid, CapProjecting, JoinMiter); +static void +refreshlisa(ModeInfo * mi) +{ + lisacons *lc = &Lisa[MI_SCREEN(mi)]; + int lctr; + + for (lctr = 0; lctr < lc->nlisajous; lctr++) { + if (!drawlisa(mi, &lc->lisajous[lctr])) + return; } } void -init_lisa(ModeInfo * mi) +refresh_lisa(ModeInfo * mi) { lisacons *lc; + + if (Lisa == NULL) + return; + lc = &Lisa[MI_SCREEN(mi)]; + if (lc->lisajous == NULL) + return; + + if (lc->painted) { + lc->painted = False; + MI_CLEARWINDOW(mi); + refreshlisa(mi); + } +} + +void +change_lisa(ModeInfo * mi) +{ + lisas *loop; + int lctr; + lisacons *lc; + + if (Lisa == NULL) + return; + lc = &Lisa[MI_SCREEN(mi)]; + if (lc->lisajous == NULL) + return; + + lc->loopcount = 0; + for (lctr = 0; lctr < lc->nlisajous; lctr++) { + loop = &lc->lisajous[lctr]; + loop->function[1] = &Function[(loop->function[0]->index + 1) % + NUMSTDFUNCS]; + loop->melting = loop->nsteps - 1; + loop->nfuncs = 2; + } +} + +void +init_lisa(ModeInfo * mi) +{ int lctr; + lisacons *lc; if (Lisa == NULL) { - if ((Lisa = (lisacons *) calloc(MI_NUM_SCREENS(mi), sizeof (lisacons))) \ - == NULL) + if ((Lisa = (lisacons *) calloc(MI_NUM_SCREENS(mi), + sizeof (lisacons))) == NULL) return; } lc = &Lisa[MI_SCREEN(mi)]; - lc->width = MI_WIN_WIDTH(mi); - lc->height = MI_WIN_HEIGHT(mi); + lc->width = MI_WIDTH(mi); + lc->height = MI_HEIGHT(mi); lc->loopcount = 0; - lc->nlisajous = MI_BATCHCOUNT(mi); + lc->nlisajous = MI_COUNT(mi); if (lc->nlisajous <= 0) lc->nlisajous = 1; + MI_CLEARWINDOW(mi); + lc->painted = False; if (lc->lisajous == NULL) { - if ((lc->lisajous = (lisas *) calloc(lc->nlisajous, sizeof (lisas))) \ - == NULL) + if ((lc->lisajous = (lisas *) calloc(lc->nlisajous, + sizeof (lisas))) == NULL) return; - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); for (lctr = 0; lctr < lc->nlisajous; lctr++) { - initlisa(mi, &lc->lisajous[lctr]); + if (!initlisa(mi, &lc->lisajous[lctr])) + return; lc->loopcount++; } } else { - refresh_lisa(mi); + refreshlisa(mi); } - XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi)); } void draw_lisa(ModeInfo * mi) { - lisacons *lc = &Lisa[MI_SCREEN(mi)]; + lisacons *lc; + if (Lisa == NULL) + return; + lc = &Lisa[MI_SCREEN(mi)]; + if (lc->lisajous == NULL) + return; + + MI_IS_DRAWN(mi) = True; + lc->painted = True; if (++lc->loopcount > lc->maxcycles) { change_lisa(mi); } - refresh_lisa(mi); -} - -void -refresh_lisa(ModeInfo * mi) -{ - lisacons *lc = &Lisa[MI_SCREEN(mi)]; - int lctr; - - for (lctr = 0; lctr < lc->nlisajous; lctr++) { - drawlisa(mi, &lc->lisajous[lctr]); - } + refreshlisa(mi); } void release_lisa(ModeInfo * mi) { - lisacons *lc; - int lctr, sctr; - if (Lisa) { - for (sctr = 0; sctr < MI_NUM_SCREENS(mi); sctr++) { - lc = &Lisa[sctr]; - while (lc->lisajous) { - for (lctr = 0; lctr < lc->nlisajous; lctr++) { - (void) free(lc->lisajous[lctr].lastpoint); - } - (void) free(lc->lisajous); - lc->lisajous = NULL; - } - } + int screen; + + for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) + free_lisa(&Lisa[screen]); (void) free(Lisa); - Lisa = NULL; + Lisa = (lisacons *) NULL; } } -void -change_lisa(ModeInfo * mi) -{ - lisacons *lc = &Lisa[MI_SCREEN(mi)]; - lisas *loop; - int lctr; - - lc->loopcount = 0; - for (lctr = 0; lctr < lc->nlisajous; lctr++) { - loop = &lc->lisajous[lctr]; - loop->function[1] = &Function[(loop->function[0]->index + 1) % - NUMSTDFUNCS]; - loop->melting = loop->nsteps - 1; - loop->nfuncs = 2; - } -} +#endif /* MODE_lisa */