sync code with last improvements from OpenBSD
This commit is contained in:
commit
88965415ff
26235 changed files with 29195616 additions and 0 deletions
334
app/xlockmore/modes/roll.c
Normal file
334
app/xlockmore/modes/roll.c
Normal file
|
@ -0,0 +1,334 @@
|
|||
/* -*- Mode: C; tab-width: 4 -*- */
|
||||
/* roll --- rolling ball of points */
|
||||
|
||||
#if !defined( lint ) && !defined( SABER )
|
||||
static const char sccsid[] = "@(#)roll.c 5.00 2000/11/01 xlockmore";
|
||||
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995 by Charles Vidal <cvidal@ivsweb.com>
|
||||
* http://www.chez.com/vidalc
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This file is provided AS IS with no warranties of any kind. The author
|
||||
* shall have no liability with respect to the infringement of copyrights,
|
||||
* trade secrets or any patents by this file or any part thereof. In no
|
||||
* event will the author be liable for any lost revenue or profits or
|
||||
* other special, indirect and consequential damages.
|
||||
*
|
||||
* Revision History:
|
||||
* 01-Nov-2000: Allocation checks
|
||||
* 10-May-1997: Compatible with xscreensaver
|
||||
* 1995: Written.
|
||||
*/
|
||||
|
||||
#ifdef STANDALONE
|
||||
#define MODE_roll
|
||||
#define PROGCLASS "Roll"
|
||||
#define HACK_INIT init_roll
|
||||
#define HACK_DRAW draw_roll
|
||||
#define roll_opts xlockmore_opts
|
||||
#define DEFAULTS "*delay: 100000 \n" \
|
||||
"*count: 25 \n" \
|
||||
"*size: -64 \n" \
|
||||
"*ncolors: 200 \n"
|
||||
#define BRIGHT_COLORS
|
||||
#define SMOOTH_COLORS
|
||||
#include "xlockmore.h" /* in xscreensaver distribution */
|
||||
#else /* STANDALONE */
|
||||
#include "xlock.h" /* in xlockmore distribution */
|
||||
#endif /* STANDALONE */
|
||||
|
||||
#ifdef MODE_roll
|
||||
|
||||
ModeSpecOpt roll_opts =
|
||||
{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
|
||||
|
||||
#ifdef USE_MODULES
|
||||
ModStruct roll_description =
|
||||
{"roll", "init_roll", "draw_roll", "release_roll",
|
||||
"refresh_roll", "init_roll", (char *) NULL, &roll_opts,
|
||||
100000, 25, 1, -64, 64, 0.6, "",
|
||||
"Shows a rolling ball", 0, NULL};
|
||||
|
||||
#endif
|
||||
|
||||
#define MINPTS 1
|
||||
#define MINSIZE 8
|
||||
#define FACTOR 8.0
|
||||
#define SPEED 25.0
|
||||
|
||||
typedef struct {
|
||||
float t, u, v;
|
||||
float t1, u1, v1;
|
||||
} ptsstruct;
|
||||
typedef struct {
|
||||
ptsstruct *pts;
|
||||
XPoint *p;
|
||||
int maxpts, npts;
|
||||
float alpha, theta, phi, r;
|
||||
XPoint sphere, direction;
|
||||
int color;
|
||||
int width, height;
|
||||
} rollstruct;
|
||||
|
||||
static rollstruct *rolls = (rollstruct *) NULL;
|
||||
|
||||
static void
|
||||
createsphere(rollstruct * rp, int n1, int n2)
|
||||
{
|
||||
double i, j;
|
||||
int n = 0;
|
||||
|
||||
for (i = 0.0; i < FACTOR * M_PI; i += (FACTOR * M_PI) / n1)
|
||||
for (j = 0.0; j < FACTOR * M_PI; j += (FACTOR * M_PI) / n2) {
|
||||
rp->pts[n].t1 = rp->r * COSF(i) * COSF(j);
|
||||
rp->pts[n].u1 = rp->r * COSF(i) * SINF(j);
|
||||
rp->pts[n].v1 = rp->r * SINF(i);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rotation3d(rollstruct * rp)
|
||||
{
|
||||
float c1, c2, c3, c4, c5, c6, c7, c8, c9, x, y, z;
|
||||
float sintheta, costheta;
|
||||
float sinphi, cosphi;
|
||||
float sinalpha, cosalpha;
|
||||
int i;
|
||||
|
||||
sintheta = SINF(rp->theta);
|
||||
costheta = COSF(rp->theta);
|
||||
sinphi = SINF(rp->phi);
|
||||
cosphi = COSF(rp->phi);
|
||||
sinalpha = SINF(rp->alpha);
|
||||
cosalpha = COSF(rp->alpha);
|
||||
|
||||
c1 = cosphi * costheta;
|
||||
c2 = sinphi * costheta;
|
||||
c3 = -sintheta;
|
||||
|
||||
c4 = cosphi * sintheta * sinalpha - sinphi * cosalpha;
|
||||
c5 = sinphi * sintheta * sinalpha + cosphi * cosalpha;
|
||||
c6 = costheta * sinalpha;
|
||||
|
||||
c7 = cosphi * sintheta * cosalpha + sinphi * sinalpha;
|
||||
c8 = sinphi * sintheta * cosalpha - cosphi * sinalpha;
|
||||
c9 = costheta * cosalpha;
|
||||
for (i = 0; i < rp->maxpts; i++) {
|
||||
x = rp->pts[i].t;
|
||||
y = rp->pts[i].u;
|
||||
z = rp->pts[i].v;
|
||||
rp->pts[i].t = c1 * x + c2 * y + c3 * z;
|
||||
rp->pts[i].u = c4 * x + c5 * y + c6 * z;
|
||||
rp->pts[i].v = c7 * x + c8 * y + c9 * z;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
project(rollstruct * rp)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rp->maxpts; i++) {
|
||||
rp->p[i].x = (short) (2 * rp->pts[i].t);
|
||||
rp->p[i].y = (short) (2 * rp->pts[i].u);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_roll(rollstruct *rp)
|
||||
{
|
||||
if (rp->pts != NULL) {
|
||||
free(rp->pts);
|
||||
rp->pts = (ptsstruct *) NULL;
|
||||
}
|
||||
if (rp->p != NULL) {
|
||||
free(rp->p);
|
||||
rp->p = (XPoint *) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init_roll(ModeInfo * mi)
|
||||
{
|
||||
int i;
|
||||
int size = MI_SIZE(mi);
|
||||
double ang;
|
||||
rollstruct *rp;
|
||||
|
||||
if (rolls == NULL) {
|
||||
if ((rolls = (rollstruct *) calloc(MI_NUM_SCREENS(mi),
|
||||
sizeof (rollstruct))) == NULL)
|
||||
return;
|
||||
}
|
||||
rp = &rolls[MI_SCREEN(mi)];
|
||||
|
||||
ang = (double) NRAND(75) + 7.5;
|
||||
rp->direction.x = (short) ((2 * (LRAND() & 1)) - 1) * (int)
|
||||
(SPEED * SINF(ang * M_PI / 180.0));
|
||||
rp->direction.y = (short) ((2 * (LRAND() & 1)) - 1) * (int)
|
||||
(SPEED * COSF(ang * M_PI / 180.0));
|
||||
rp->width = MI_WIDTH(mi);
|
||||
rp->height = MI_HEIGHT(mi);
|
||||
if (size < -MINSIZE)
|
||||
rp->r = NRAND(MIN(-size, MAX(MINSIZE,
|
||||
MIN(rp->width, rp->height) / 4)) - MINSIZE + 1) + MINSIZE;
|
||||
else if (size < MINSIZE) {
|
||||
if (!size)
|
||||
rp->r = MAX(MINSIZE, MIN(rp->width, rp->height) / 4);
|
||||
else
|
||||
rp->r = MINSIZE;
|
||||
} else
|
||||
rp->r = MIN(size, MAX(MINSIZE,
|
||||
MIN(rp->width, rp->height) / 4));
|
||||
rp->sphere.x = NRAND(MAX(1, rp->width - 4 * (int) rp->r)) +
|
||||
2 * (int) rp->r;
|
||||
rp->sphere.y = NRAND(MAX(1, rp->height - 4 * (int) rp->r)) +
|
||||
2 * (int) rp->r;
|
||||
rp->alpha = 0;
|
||||
rp->theta = 0;
|
||||
rp->phi = 0;
|
||||
rp->maxpts = MI_COUNT(mi);
|
||||
if (rp->maxpts < -MINPTS) {
|
||||
/* if rp->maxpts is random ... the size can change */
|
||||
if (rp->pts != NULL) {
|
||||
free(rp->pts);
|
||||
rp->pts = (ptsstruct *) NULL;
|
||||
}
|
||||
rp->maxpts = NRAND(-rp->maxpts - MINPTS + 1) + MINPTS;
|
||||
} else if (rp->maxpts < MINPTS)
|
||||
rp->maxpts = MINPTS;
|
||||
i = rp->maxpts;
|
||||
rp->maxpts *= rp->maxpts;
|
||||
rp->npts = 0;
|
||||
if (rp->pts == NULL)
|
||||
if ((rp->pts = (ptsstruct *) malloc(rp->maxpts *
|
||||
sizeof (ptsstruct))) ==NULL) {
|
||||
free_roll(rp);
|
||||
return;
|
||||
}
|
||||
if (rp->p != NULL) {
|
||||
free(rp->p);
|
||||
rp->p = (XPoint *) NULL;
|
||||
}
|
||||
if (MI_NPIXELS(mi) > 2)
|
||||
rp->color = NRAND(MI_NPIXELS(mi));
|
||||
createsphere(rp, i, i);
|
||||
|
||||
MI_CLEARWINDOW(mi);
|
||||
}
|
||||
|
||||
void
|
||||
draw_roll(ModeInfo * mi)
|
||||
{
|
||||
Display *display = MI_DISPLAY(mi);
|
||||
Window window = MI_WINDOW(mi);
|
||||
GC gc = MI_GC(mi);
|
||||
int i;
|
||||
rollstruct *rp;
|
||||
|
||||
if (rolls == NULL)
|
||||
return;
|
||||
rp = &rolls[MI_SCREEN(mi)];
|
||||
if (rp->pts == NULL)
|
||||
return;
|
||||
|
||||
MI_IS_DRAWN(mi) = True;
|
||||
for (i = 0; i < rp->maxpts; i++) {
|
||||
rp->pts[i].t = rp->pts[i].t1;
|
||||
rp->pts[i].u = rp->pts[i].u1;
|
||||
rp->pts[i].v = rp->pts[i].v1;
|
||||
}
|
||||
rp->alpha += ((FACTOR * M_PI) / 200.0);
|
||||
rp->theta += ((FACTOR * M_PI) / 200.0);
|
||||
rp->phi += ((FACTOR * M_PI) / 200.0);
|
||||
if (rp->alpha > (FACTOR * M_PI))
|
||||
rp->alpha -= (FACTOR * M_PI);
|
||||
if (rp->theta > (FACTOR * M_PI))
|
||||
rp->theta -= (FACTOR * M_PI);
|
||||
if (rp->phi > (FACTOR * M_PI))
|
||||
rp->phi -= (FACTOR * M_PI);
|
||||
|
||||
if (rp->npts) {
|
||||
XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
|
||||
XDrawPoints(display, window, gc, rp->p, rp->npts, CoordModeOrigin);
|
||||
} else {
|
||||
if (rp->p)
|
||||
free(rp->p);
|
||||
if ((rp->p = (XPoint *) malloc(rp->maxpts *
|
||||
sizeof (XPoint))) == NULL) {
|
||||
free_roll(rp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
rotation3d(rp);
|
||||
project(rp);
|
||||
rp->npts = 0;
|
||||
for (i = 0; i < rp->maxpts; i++) {
|
||||
if (rp->pts[i].v > 0.0) {
|
||||
rp->p[rp->npts].x += rp->sphere.x;
|
||||
rp->p[rp->npts].y += rp->sphere.y;
|
||||
rp->npts++;
|
||||
}
|
||||
}
|
||||
if (MI_NPIXELS(mi) <= 2)
|
||||
XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
|
||||
else {
|
||||
rp->color = (rp->color + 1) % MI_NPIXELS(mi);
|
||||
XSetForeground(display, gc, MI_PIXEL(mi, rp->color));
|
||||
}
|
||||
XDrawPoints(display, window, gc, rp->p, rp->npts, CoordModeOrigin);
|
||||
if (rp->sphere.x >= rp->width - (int) rp->r && rp->direction.x > 0)
|
||||
rp->direction.x = -rp->direction.x;
|
||||
else if (rp->sphere.x <= (int) rp->r && rp->direction.x < 0)
|
||||
rp->direction.x = -rp->direction.x;
|
||||
else if (rp->sphere.x < rp->width - 2 * (int) rp->r ||
|
||||
rp->sphere.x > 2 * (int) rp->r) {
|
||||
if (rp->sphere.x >= rp->width - 2 * (int) rp->r && rp->direction.x > 0)
|
||||
rp->direction.x = -rp->direction.x;
|
||||
else if (rp->sphere.x <= 2 * (int) rp->r && rp->direction.x < 0)
|
||||
rp->direction.x = -rp->direction.x;
|
||||
}
|
||||
if (rp->sphere.y >= rp->height - (int) rp->r && rp->direction.y > 0)
|
||||
rp->direction.y = -rp->direction.y;
|
||||
else if (rp->sphere.y <= (int) rp->r && rp->direction.y < 0)
|
||||
rp->direction.y = -rp->direction.y;
|
||||
else if (rp->sphere.y < rp->height - 2 * (int) rp->r ||
|
||||
rp->sphere.y > 2 * (int) rp->r) {
|
||||
if (rp->sphere.y >= rp->height - 2 * (int) rp->r && rp->direction.y > 0)
|
||||
rp->direction.y = -rp->direction.y;
|
||||
else if (rp->sphere.y <= 2 * (int) rp->r && rp->direction.y < 0)
|
||||
rp->direction.y = -rp->direction.y;
|
||||
}
|
||||
rp->sphere.x += rp->direction.x;
|
||||
rp->sphere.y += rp->direction.y;
|
||||
}
|
||||
|
||||
void
|
||||
release_roll(ModeInfo * mi)
|
||||
{
|
||||
if (rolls != NULL) {
|
||||
int screen;
|
||||
|
||||
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
|
||||
free_roll(&rolls[screen]);
|
||||
free(rolls);
|
||||
rolls = (rollstruct *) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
refresh_roll(ModeInfo * mi)
|
||||
{
|
||||
MI_CLEARWINDOW(mi);
|
||||
}
|
||||
|
||||
#endif /* MODE_roll */
|
Loading…
Add table
Add a link
Reference in a new issue