"Fossies" - the Fresh Open Source Software Archive

Member "xlockmore-5.59/modes/roll.c" (8 Sep 2019, 8782 Bytes) of package /linux/misc/xlockmore-5.59.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "roll.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.58_vs_5.59.

    1 /* -*- Mode: C; tab-width: 4 -*- */
    2 /* roll --- rolling ball of points */
    3 
    4 #if 0
    5 static const char sccsid[] = "@(#)roll.c    5.00 2000/11/01 xlockmore";
    6 
    7 #endif
    8 
    9 /*-
   10  * Copyright (c) 1995 by Charles Vidal <cvidal AT ivsweb.com>
   11  *         http://www.chez.com/vidalc
   12  *
   13  * Permission to use, copy, modify, and distribute this software and its
   14  * documentation for any purpose and without fee is hereby granted,
   15  * provided that the above copyright notice appear in all copies and that
   16  * both that copyright notice and this permission notice appear in
   17  * supporting documentation.
   18  *
   19  * This file is provided AS IS with no warranties of any kind.  The author
   20  * shall have no liability with respect to the infringement of copyrights,
   21  * trade secrets or any patents by this file or any part thereof.  In no
   22  * event will the author be liable for any lost revenue or profits or
   23  * other special, indirect and consequential damages.
   24  *
   25  * Revision History:
   26  * 01-Nov-2000: Allocation checks
   27  * 10-May-1997:  Compatible with xscreensaver
   28  * 1995: Written.
   29  */
   30 
   31 #ifdef STANDALONE
   32 #define MODE_roll
   33 #define DEFAULTS "*delay: 100000 \n" \
   34     "*count: 25 \n" \
   35     "*size: -64 \n" \
   36     "*ncolors: 200 \n" \
   37 
   38 # define reshape_roll 0
   39 # define roll_handle_event 0
   40 #define BRIGHT_COLORS
   41 #define SMOOTH_COLORS
   42 #include "xlockmore.h"      /* in xscreensaver distribution */
   43 #else /* STANDALONE */
   44 #include "xlock.h"      /* in xlockmore distribution */
   45 #endif /* STANDALONE */
   46 
   47 #ifdef MODE_roll
   48 
   49 ENTRYPOINT ModeSpecOpt roll_opts =
   50 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
   51 
   52 #ifdef USE_MODULES
   53 ModStruct   roll_description =
   54 {"roll", "init_roll", "draw_roll", "release_roll",
   55  "refresh_roll", "init_roll", "free_roll", &roll_opts,
   56  100000, 25, 1, -64, 64, 0.6, "",
   57  "Shows a rolling ball", 0, NULL};
   58 
   59 #endif
   60 
   61 #define MINPTS 1
   62 #define MINSIZE 8
   63 #define FACTOR 8.0
   64 #define SPEED 25.0
   65 
   66 typedef struct {
   67     float       t, u, v;
   68     float       t1, u1, v1;
   69 } ptsstruct;
   70 typedef struct {
   71     ptsstruct  *pts;
   72     XPoint     *p;
   73     int         maxpts, npts;
   74     float       alpha, theta, phi, r;
   75     XPoint      sphere, direction;
   76     int         color;
   77     int         width, height;
   78 } rollstruct;
   79 
   80 static rollstruct *rolls = (rollstruct *) NULL;
   81 
   82 static void
   83 createsphere(rollstruct * rp, int n1, int n2)
   84 {
   85     double      i, j;
   86     int         n = 0;
   87 
   88     for (i = 0.0; i < FACTOR * M_PI; i += (FACTOR * M_PI) / n1)
   89         for (j = 0.0; j < FACTOR * M_PI; j += (FACTOR * M_PI) / n2) {
   90             rp->pts[n].t1 = rp->r * COSF(i) * COSF(j);
   91             rp->pts[n].u1 = rp->r * COSF(i) * SINF(j);
   92             rp->pts[n].v1 = rp->r * SINF(i);
   93             n++;
   94         }
   95 }
   96 
   97 static void
   98 rotation3d(rollstruct * rp)
   99 {
  100     float       c1, c2, c3, c4, c5, c6, c7, c8, c9, x, y, z;
  101     float       sintheta, costheta;
  102     float       sinphi, cosphi;
  103     float       sinalpha, cosalpha;
  104     int         i;
  105 
  106     sintheta = SINF(rp->theta);
  107     costheta = COSF(rp->theta);
  108     sinphi = SINF(rp->phi);
  109     cosphi = COSF(rp->phi);
  110     sinalpha = SINF(rp->alpha);
  111     cosalpha = COSF(rp->alpha);
  112 
  113     c1 = cosphi * costheta;
  114     c2 = sinphi * costheta;
  115     c3 = -sintheta;
  116 
  117     c4 = cosphi * sintheta * sinalpha - sinphi * cosalpha;
  118     c5 = sinphi * sintheta * sinalpha + cosphi * cosalpha;
  119     c6 = costheta * sinalpha;
  120 
  121     c7 = cosphi * sintheta * cosalpha + sinphi * sinalpha;
  122     c8 = sinphi * sintheta * cosalpha - cosphi * sinalpha;
  123     c9 = costheta * cosalpha;
  124     for (i = 0; i < rp->maxpts; i++) {
  125         x = rp->pts[i].t;
  126         y = rp->pts[i].u;
  127         z = rp->pts[i].v;
  128         rp->pts[i].t = c1 * x + c2 * y + c3 * z;
  129         rp->pts[i].u = c4 * x + c5 * y + c6 * z;
  130         rp->pts[i].v = c7 * x + c8 * y + c9 * z;
  131     }
  132 }
  133 
  134 static void
  135 project(rollstruct * rp)
  136 {
  137     int         i;
  138 
  139     for (i = 0; i < rp->maxpts; i++) {
  140         rp->p[i].x = (short) (2 * rp->pts[i].t);
  141         rp->p[i].y = (short) (2 * rp->pts[i].u);
  142     }
  143 }
  144 
  145 static void
  146 free_roll_screen(rollstruct *rp)
  147 {
  148     if (rp == NULL) {
  149         return;
  150     }
  151     if (rp->pts != NULL) {
  152         free(rp->pts);
  153         rp->pts = (ptsstruct *) NULL;
  154     }
  155     if (rp->p != NULL) {
  156         free(rp->p);
  157         rp->p = (XPoint *) NULL;
  158     }
  159     rp = NULL;
  160 }
  161 
  162 ENTRYPOINT void
  163 free_roll(ModeInfo * mi)
  164 {
  165     free_roll_screen(&rolls[MI_SCREEN(mi)]);
  166 }
  167 
  168 ENTRYPOINT void
  169 init_roll(ModeInfo * mi)
  170 {
  171     int         i;
  172     int         size = MI_SIZE(mi);
  173     double      ang;
  174     rollstruct *rp;
  175 
  176     MI_INIT(mi, rolls);
  177     rp = &rolls[MI_SCREEN(mi)];
  178 
  179     ang = (double) NRAND(75) + 7.5;
  180     rp->direction.x = (short) ((2 * (LRAND() & 1)) - 1) * (int)
  181         (SPEED * SINF(ang * M_PI / 180.0));
  182     rp->direction.y = (short) ((2 * (LRAND() & 1)) - 1) * (int)
  183         (SPEED * COSF(ang * M_PI / 180.0));
  184     rp->width = MI_WIDTH(mi);
  185     rp->height = MI_HEIGHT(mi);
  186     if (size < -MINSIZE)
  187         rp->r = NRAND(MIN(-size, MAX(MINSIZE,
  188            MIN(rp->width, rp->height) / 4)) - MINSIZE + 1) + MINSIZE;
  189     else if (size < MINSIZE) {
  190         if (!size)
  191             rp->r = MAX(MINSIZE, MIN(rp->width, rp->height) / 4);
  192         else
  193             rp->r = MINSIZE;
  194     } else
  195         rp->r = MIN(size, MAX(MINSIZE,
  196                       MIN(rp->width, rp->height) / 4));
  197     rp->sphere.x = NRAND(MAX(1, rp->width - 4 * (int) rp->r)) +
  198         2 * (int) rp->r;
  199     rp->sphere.y = NRAND(MAX(1, rp->height - 4 * (int) rp->r)) +
  200         2 * (int) rp->r;
  201     rp->alpha = 0;
  202     rp->theta = 0;
  203     rp->phi = 0;
  204     rp->maxpts = MI_COUNT(mi);
  205     if (rp->maxpts < -MINPTS) {
  206         /* if rp->maxpts is random ... the size can change */
  207         if (rp->pts != NULL) {
  208             free(rp->pts);
  209             rp->pts = (ptsstruct *) NULL;
  210         }
  211         rp->maxpts = NRAND(-rp->maxpts - MINPTS + 1) + MINPTS;
  212     } else if (rp->maxpts < MINPTS)
  213         rp->maxpts = MINPTS;
  214     i = rp->maxpts;
  215     rp->maxpts *= rp->maxpts;
  216     rp->npts = 0;
  217     if (rp->pts == NULL)
  218         if ((rp->pts = (ptsstruct *) malloc(rp->maxpts *
  219                 sizeof (ptsstruct))) ==NULL) {
  220             free_roll_screen(rp);
  221             return;
  222         }
  223     if (rp->p != NULL) {
  224         free(rp->p);
  225         rp->p = (XPoint *) NULL;
  226     }
  227     if (MI_NPIXELS(mi) > 2)
  228         rp->color = NRAND(MI_NPIXELS(mi));
  229     createsphere(rp, i, i);
  230 
  231     MI_CLEARWINDOW(mi);
  232 }
  233 
  234 ENTRYPOINT void
  235 draw_roll(ModeInfo * mi)
  236 {
  237     Display    *display = MI_DISPLAY(mi);
  238     Window      window = MI_WINDOW(mi);
  239     GC          gc = MI_GC(mi);
  240     int         i;
  241     rollstruct *rp;
  242 
  243     if (rolls == NULL)
  244         return;
  245     rp = &rolls[MI_SCREEN(mi)];
  246     if (rp->pts == NULL)
  247         return;
  248 
  249     MI_IS_DRAWN(mi) = True;
  250     for (i = 0; i < rp->maxpts; i++) {
  251         rp->pts[i].t = rp->pts[i].t1;
  252         rp->pts[i].u = rp->pts[i].u1;
  253         rp->pts[i].v = rp->pts[i].v1;
  254     }
  255     rp->alpha += ((FACTOR * M_PI) / 200.0);
  256     rp->theta += ((FACTOR * M_PI) / 200.0);
  257     rp->phi += ((FACTOR * M_PI) / 200.0);
  258     if (rp->alpha > (FACTOR * M_PI))
  259         rp->alpha -= (FACTOR * M_PI);
  260     if (rp->theta > (FACTOR * M_PI))
  261         rp->theta -= (FACTOR * M_PI);
  262     if (rp->phi > (FACTOR * M_PI))
  263         rp->phi -= (FACTOR * M_PI);
  264 
  265     if (rp->npts) {
  266         XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
  267         XDrawPoints(display, window, gc, rp->p, rp->npts, CoordModeOrigin);
  268     } else {
  269         if (rp->p)
  270             free(rp->p);
  271         if ((rp->p = (XPoint *) malloc(rp->maxpts *
  272                 sizeof (XPoint))) == NULL) {
  273             free_roll_screen(rp);
  274             return;
  275         }
  276     }
  277     rotation3d(rp);
  278     project(rp);
  279     rp->npts = 0;
  280     for (i = 0; i < rp->maxpts; i++) {
  281         if (rp->pts[i].v > 0.0) {
  282             rp->p[rp->npts].x += rp->sphere.x;
  283             rp->p[rp->npts].y += rp->sphere.y;
  284             rp->npts++;
  285         }
  286     }
  287     if (MI_NPIXELS(mi) <= 2)
  288         XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
  289     else {
  290         rp->color = (rp->color + 1) % MI_NPIXELS(mi);
  291         XSetForeground(display, gc, MI_PIXEL(mi, rp->color));
  292     }
  293     XDrawPoints(display, window, gc, rp->p, rp->npts, CoordModeOrigin);
  294     if (rp->sphere.x >= rp->width - (int) rp->r && rp->direction.x > 0)
  295         rp->direction.x = -rp->direction.x;
  296     else if (rp->sphere.x <= (int) rp->r && rp->direction.x < 0)
  297         rp->direction.x = -rp->direction.x;
  298     else if (rp->sphere.x < rp->width - 2 * (int) rp->r ||
  299          rp->sphere.x > 2 * (int) rp->r) {
  300         if (rp->sphere.x >= rp->width - 2 * (int) rp->r && rp->direction.x > 0)
  301             rp->direction.x = -rp->direction.x;
  302         else if (rp->sphere.x <= 2 * (int) rp->r && rp->direction.x < 0)
  303             rp->direction.x = -rp->direction.x;
  304     }
  305     if (rp->sphere.y >= rp->height - (int) rp->r && rp->direction.y > 0)
  306         rp->direction.y = -rp->direction.y;
  307     else if (rp->sphere.y <= (int) rp->r && rp->direction.y < 0)
  308         rp->direction.y = -rp->direction.y;
  309     else if (rp->sphere.y < rp->height - 2 * (int) rp->r ||
  310          rp->sphere.y > 2 * (int) rp->r) {
  311         if (rp->sphere.y >= rp->height - 2 * (int) rp->r && rp->direction.y > 0)
  312             rp->direction.y = -rp->direction.y;
  313         else if (rp->sphere.y <= 2 * (int) rp->r && rp->direction.y < 0)
  314             rp->direction.y = -rp->direction.y;
  315     }
  316     rp->sphere.x += rp->direction.x;
  317     rp->sphere.y += rp->direction.y;
  318 }
  319 
  320 ENTRYPOINT void
  321 release_roll(ModeInfo * mi)
  322 {
  323     if (rolls != NULL) {
  324         int         screen;
  325 
  326         for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
  327             free_roll_screen(&rolls[screen]);
  328         free(rolls);
  329         rolls = (rollstruct *) NULL;
  330     }
  331 }
  332 
  333 #ifndef STANDALONE
  334 ENTRYPOINT void
  335 refresh_roll(ModeInfo * mi)
  336 {
  337     MI_CLEARWINDOW(mi);
  338 }
  339 #endif
  340 
  341 XSCREENSAVER_MODULE ("Roll", roll)
  342 
  343 #endif /* MODE_roll */