slrn: obsolete
[oi-userland.git] / components / x11 / xlock / src / flame.c
blob2b82e1a92ab1f612d275a0f58949d1b862e1b8df
1 /*
2 * Copyright (c) 1988-91 by Patrick J. Naughton.
4 * Permission to use, copy, modify, and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted,
6 * provided that the above copyright notice appear in all copies and that
7 * both that copyright notice and this permission notice appear in
8 * supporting documentation.
10 * This file is provided AS IS with no warranties of any kind. The author
11 * shall have no liability with respect to the infringement of copyrights,
12 * trade secrets or any patents by this file or any part thereof. In no
13 * event will the author be liable for any lost revenue or profits or
14 * other special, indirect and consequential damages.
18 * Copyright (c) 1991, 2015, Oracle and/or its affiliates. All rights reserved.
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
27 * The above copyright notice and this permission notice (including the next
28 * paragraph) shall be included in all copies or substantial portions of the
29 * Software.
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
34 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
36 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
37 * DEALINGS IN THE SOFTWARE.
40 /*-
41 * flame.c - recursive fractal cosmic dust.
43 * Copyright (c) 1991 by Patrick J. Naughton.
45 * See xlock.c for copying information.
47 * Revision History:
48 * 24-Jun-91: fixed portability problem with integer mod (%).
49 * 06-Jun-91: Written. (received from Spot, spot@cs.cmu.edu).
52 #include "xlock.h"
53 #include <math.h>
55 #define MAXTOTAL 10000
56 #define MAXBATCH 10
58 typedef struct {
59 double f[2][3][20]; /* three non-homogeneous transforms */
60 int max_levels;
61 int cur_level;
62 int SNUM;
63 int ANUM;
64 int width, height;
65 int num_points;
66 int total_points;
67 int pixcol;
68 Window win;
69 XPoint pts[MAXBATCH];
70 } flamestruct;
72 static flamestruct flames[MAXSCREENS];
74 static short
75 halfrandom(int mv)
77 static short lasthalf = 0;
78 unsigned long r;
80 if (lasthalf) {
81 r = (unsigned long) lasthalf;
82 lasthalf = 0;
83 } else {
84 r = (unsigned long) random();
85 lasthalf = (short) (r >> 16);
87 return (short) (r % mv);
90 void
91 initflame(Window win)
93 flamestruct *fs = &flames[screen];
94 XWindowAttributes xwa;
96 srandom((uint_t) time((long *) 0));
98 if ((batchcount < 1) || (batchcount > 64))
99 batchcount = 20;
101 XGetWindowAttributes(dsp, win, &xwa);
102 fs->width = xwa.width;
103 fs->height = xwa.height;
105 fs->max_levels = batchcount;
106 fs->win = win;
108 XSetForeground(dsp, Scr[screen].gc, ssblack[screen].pixel);
109 XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, fs->width, fs->height);
111 if (Scr[screen].npixels > 2) {
112 fs->pixcol = halfrandom(Scr[screen].npixels);
113 XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[fs->pixcol]);
114 } else {
115 XSetForeground(dsp, Scr[screen].gc, sswhite[screen].pixel);
119 static Bool
120 recurse(
121 flamestruct *fs,
122 double x,
123 double y,
124 int l
127 if (l == fs->max_levels) {
128 fs->total_points++;
129 if (fs->total_points > MAXTOTAL) /* how long each fractal runs */
130 return False;
132 if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) {
133 fs->pts[fs->num_points].x = (short) ((fs->width / 2) * (x + 1.0));
134 fs->pts[fs->num_points].y = (short) ((fs->height / 2) * (y + 1.0));
135 fs->num_points++;
136 if (fs->num_points > MAXBATCH) { /* point buffer size */
137 XDrawPoints(dsp, fs->win, Scr[screen].gc, fs->pts,
138 fs->num_points, CoordModeOrigin);
139 fs->num_points = 0;
142 } else {
143 int i;
144 for (i = 0; i < fs->SNUM; i++) {
145 double nx, ny;
146 nx = fs->f[0][0][i] * x + fs->f[0][1][i] * y + fs->f[0][2][i];
147 ny = fs->f[1][0][i] * x + fs->f[1][1][i] * y + fs->f[1][2][i];
148 if (i < fs->ANUM) {
149 nx = sin(nx);
150 ny = sin(ny);
152 if (!recurse(fs, nx, ny, l + 1))
153 return False;
156 return True;
160 void
161 drawflame(Window win)
163 flamestruct *fs = &flames[screen];
165 int i, j, k;
166 static int alt = 0;
168 if (!(fs->cur_level++ % fs->max_levels)) {
169 XClearWindow(dsp, fs->win);
170 alt = !alt;
171 } else {
172 if (Scr[screen].npixels > 2) {
173 XSetForeground(dsp, Scr[screen].gc,
174 Scr[screen].pixels[fs->pixcol]);
175 if (--fs->pixcol < 0)
176 fs->pixcol = Scr[screen].npixels - 1;
180 /* number of functions */
181 fs->SNUM = 2 + (fs->cur_level % 3);
183 /* how many of them are of alternate form */
184 if (alt)
185 fs->ANUM = 0;
186 else
187 fs->ANUM = halfrandom(fs->SNUM) + 2;
189 /* 6 coefs per function */
190 for (k = 0; k < fs->SNUM; k++) {
191 for (i = 0; i < 2; i++)
192 for (j = 0; j < 3; j++)
193 fs->f[i][j][k] = ((double) (random() & 1023) / 512.0 - 1.0);
195 fs->num_points = 0;
196 fs->total_points = 0;
197 (void) recurse(fs, 0.0, 0.0, 0);
198 XDrawPoints(dsp, win, Scr[screen].gc,
199 fs->pts, fs->num_points, CoordModeOrigin);