source: trunk/third/xscreensaver/hacks/mountain.c @ 20148

Revision 20148, 7.1 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20147, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 4 -*- */
2/* mountain -- square grid mountains */
3
4#if 0
5static const char sccsid[] = "@(#)mountain.c    5.00 2000/11/01 xlockmore";
6#endif
7
8/*-
9 * Copyright (c) 1995 Pascal Pensa <pensa@aurora.unice.fr>
10 *
11 * Permission to use, copy, modify, and distribute this software and its
12 * documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation.
16 *
17 * This file is provided AS IS with no warranties of any kind.  The author
18 * shall have no liability with respect to the infringement of copyrights,
19 * trade secrets or any patents by this file or any part thereof.  In no
20 * event will the author be liable for any lost revenue or profits or
21 * other special, indirect and consequential damages.
22 *
23 * Revision History:
24 * 01-Nov-2000: Allocation checks
25 * 10-May-1997: Compatible with xscreensaver
26 * 1995: Written
27 */
28
29#ifdef STANDALONE
30#define MODE_mountain
31#define PROGCLASS "Mountain"
32#define HACK_INIT init_mountain
33#define HACK_DRAW draw_mountain
34#define mountain_opts xlockmore_opts
35#define DEFAULTS "*delay: 1000 \n" \
36 "*count: 30 \n" \
37 "*cycles: 4000 \n" \
38 "*ncolors: 64 \n"
39#define SMOOTH_COLORS
40#include "xlockmore.h"          /* in xscreensaver distribution */
41#else /* STANDALONE */
42#include "xlock.h"              /* in xlockmore distribution */
43#endif /* STANDALONE */
44
45#ifdef MODE_mountain
46
47ModeSpecOpt mountain_opts =
48{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
49
50#ifdef USE_MODULES
51ModStruct   mountain_description =
52{"mountain", "init_mountain", "draw_mountain", "release_mountain",
53 "refresh_mountain", "init_mountain", (char *) NULL, &mountain_opts,
54 1000, 30, 4000, 1, 64, 1.0, "",
55 "Shows Papo's mountain range", 0, NULL};
56
57#endif
58
59/* ~ 5000 Max mountain height (1000 - 10000) */
60#define MAXHEIGHT  (3 * (mp->width + mp->height))
61
62#define WORLDWIDTH 50           /* World size x * y */
63
64#define RANGE_RAND(min,max) ((min) + NRAND((max) - (min)))
65
66typedef struct {
67        int         pixelmode;
68        int         width;
69        int         height;
70        int         x, y;
71        int         offset;
72        int         stage;
73        int         h[WORLDWIDTH][WORLDWIDTH];
74        long        time;       /* up time */
75        Bool        wireframe;
76        Bool        joke;
77        GC          stippledGC;
78} mountainstruct;
79
80static mountainstruct *mountains = (mountainstruct *) NULL;
81
82static void
83spread(int  (*m)[50], int x, int y)
84{
85        int         x2, y2;
86        int         h = m[x][y];
87
88        for (y2 = y - 1; y2 <= y + 1; y2++)
89                for (x2 = x - 1; x2 <= x + 1; x2++)
90                        if (x2 >= 0 && y2 >= 0 && x2 < WORLDWIDTH && y2 < WORLDWIDTH)
91                                m[x2][y2] = (m[x2][y2] + h) / 2;
92}
93
94static void
95drawamountain(ModeInfo * mi)
96{
97        Display    *display = MI_DISPLAY(mi);
98        Window      window = MI_WINDOW(mi);
99        GC          gc = MI_GC(mi);
100        mountainstruct *mp = &mountains[MI_SCREEN(mi)];
101        int         x2, y2, x3, y3, y4, y5, c = 0;
102        XPoint      p[5];
103
104        if (MI_NPIXELS(mi) > 2) {
105                c = (mp->h[mp->x][mp->y] + mp->h[mp->x + 1][mp->y] +
106                  mp->h[mp->x][mp->y + 1] + mp->h[mp->x + 1][mp->y + 1]) / 4;
107                c = (c / 10 + mp->offset) % MI_NPIXELS(mi);
108        }
109        x2 = mp->x * (2 * mp->width) / (3 * WORLDWIDTH);
110        y2 = mp->y * (2 * mp->height) / (3 * WORLDWIDTH);
111        p[0].x = (x2 - y2 / 2) + (mp->width / 4);
112        p[0].y = (y2 - mp->h[mp->x][mp->y]) + mp->height / 4;
113
114        x3 = (mp->x + 1) * (2 * mp->width) / (3 * WORLDWIDTH);
115        y3 = mp->y * (2 * mp->height) / (3 * WORLDWIDTH);
116        p[1].x = (x3 - y3 / 2) + (mp->width / 4);
117        p[1].y = (y3 - mp->h[mp->x + 1][mp->y]) + mp->height / 4;
118
119        y4 = (mp->y + 1) * (2 * mp->height) / (3 * WORLDWIDTH);
120        p[2].x = (x3 - y4 / 2) + (mp->width / 4);
121        p[2].y = (y4 - mp->h[mp->x + 1][mp->y + 1]) + mp->height / 4;
122
123        y5 = (mp->y + 1) * (2 * mp->height) / (3 * WORLDWIDTH);
124        p[3].x = (x2 - y5 / 2) + (mp->width / 4);
125        p[3].y = (y5 - mp->h[mp->x][mp->y + 1]) + mp->height / 4;
126
127        p[4].x = p[0].x;
128        p[4].y = p[0].y;
129
130        if (MI_NPIXELS(mi) > 2)
131                XSetForeground(display, gc, MI_PIXEL(mi, c));
132        else
133                XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
134
135        if (mp->joke) {
136                if ((Bool) (LRAND() & 1))
137                        XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
138                else {
139                        XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin);
140                        if (!mp->pixelmode) {
141                                XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
142                                XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
143                        }
144                }
145        } else {
146                if (mp->wireframe) {
147                        XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
148                } else {
149                        XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin);
150
151                        if (!mp->pixelmode) {
152                                XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
153                                XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
154                        }
155                }
156        }
157        mp->x++;
158        if (mp->x == WORLDWIDTH - 1) {
159                mp->y++;
160                mp->x = 0;
161        }
162        if (mp->y == WORLDWIDTH - 1)
163                mp->stage++;
164}
165
166void
167init_mountain(ModeInfo * mi)
168{
169        int         i, j, x, y;
170        XGCValues   gcv;
171        mountainstruct *mp;
172
173        if (mountains == NULL) {
174                if ((mountains = (mountainstruct *) calloc(MI_NUM_SCREENS(mi),
175                                           sizeof (mountainstruct))) == NULL)
176                        return;
177        }
178        mp = &mountains[MI_SCREEN(mi)];
179
180        mp->width = MI_WIDTH(mi);
181        mp->height = MI_HEIGHT(mi);
182        mp->pixelmode = (mp->width + mp->height < 200);
183        mp->stage = 0;
184        mp->time = 0;
185        mp->x = mp->y = 0;
186        if (MI_IS_FULLRANDOM(mi)) {
187                mp->joke = (Bool) (NRAND(10) == 0);
188                mp->wireframe = (Bool) (LRAND() & 1);
189        } else {
190                mp->joke = False;
191                mp->wireframe = MI_IS_WIREFRAME(mi);
192        }
193
194        if (mp->stippledGC == None) {
195                gcv.foreground = MI_WHITE_PIXEL(mi);
196                gcv.background = MI_BLACK_PIXEL(mi);
197                if ((mp->stippledGC = XCreateGC(MI_DISPLAY(mi), MI_WINDOW(mi),
198                                          GCForeground | GCBackground, &gcv)) == None)
199                        return;
200        }
201        MI_CLEARWINDOW(mi);
202
203        for (y = 0; y < (int) WORLDWIDTH; y++)
204                for (x = 0; x < (int) WORLDWIDTH; x++)
205                        mp->h[x][y] = 0;
206
207        j = MI_COUNT(mi);
208        if (j < 0)
209                j = NRAND(-j) + 1;
210        for (i = 0; i < j; i++)
211                mp->h[RANGE_RAND(1, WORLDWIDTH - 1)][RANGE_RAND(1, WORLDWIDTH - 1)] =
212                        NRAND(MAXHEIGHT);
213
214        for (y = 0; y < WORLDWIDTH; y++)
215                for (x = 0; x < WORLDWIDTH; x++)
216                        spread(mp->h, x, y);
217
218        for (y = 0; y < WORLDWIDTH; y++)
219                for (x = 0; x < WORLDWIDTH; x++) {
220                        mp->h[x][y] = mp->h[x][y] + NRAND(10) - 5;
221                        if (mp->h[x][y] < 10)
222                                mp->h[x][y] = 0;
223                }
224
225        if (MI_NPIXELS(mi) > 2)
226                mp->offset = NRAND(MI_NPIXELS(mi));
227        else
228                mp->offset = 0;
229}
230
231void
232draw_mountain(ModeInfo * mi)
233{
234        mountainstruct *mp;
235
236        if (mountains == NULL)
237                        return;
238        mp = &mountains[MI_SCREEN(mi)];
239        if (mp->stippledGC == NULL)
240                        return;
241
242        MI_IS_DRAWN(mi) = True;
243
244        switch (mp->stage) {
245                case 0:
246                        drawamountain(mi);
247                        break;
248                case 1:
249                        if (++mp->time > MI_CYCLES(mi))
250                                mp->stage++;
251                        break;
252                case 2:
253                        init_mountain(mi);
254                        break;
255        }
256}
257
258void
259release_mountain(ModeInfo * mi)
260{
261        if (mountains != NULL) {
262                int         screen;
263
264                for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
265                        mountainstruct *mp = &mountains[screen];
266
267                        if (mp->stippledGC)
268                                XFreeGC(MI_DISPLAY(mi), mp->stippledGC);
269                }
270                (void) free((void *) mountains);
271                mountains = (mountainstruct *) NULL;
272        }
273}
274
275void
276refresh_mountain(ModeInfo * mi)
277{
278        mountainstruct *mp;
279
280        if (mountains == NULL)
281                        return;
282        mp = &mountains[MI_SCREEN(mi)];
283
284        MI_CLEARWINDOW(mi);
285        mp->x = 0;
286        mp->y = 0;
287}
288
289#endif /* MODE_mountain */
Note: See TracBrowser for help on using the repository browser.