summaryrefslogtreecommitdiffstats
path: root/hacks/mountain.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/mountain.c')
-rw-r--r--hacks/mountain.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/hacks/mountain.c b/hacks/mountain.c
new file mode 100644
index 0000000..541b187
--- /dev/null
+++ b/hacks/mountain.c
@@ -0,0 +1,282 @@
+/* -*- Mode: C; tab-width: 4 -*- */
+/* mountain -- square grid mountains */
+
+#if 0
+static const char sccsid[] = "@(#)mountain.c 5.00 2000/11/01 xlockmore";
+#endif
+
+/*-
+ * Copyright (c) 1995 Pascal Pensa <pensa@aurora.unice.fr>
+ *
+ * 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_mountain
+#define DEFAULTS "*delay: 20000 \n" \
+ "*count: 30 \n" \
+ "*cycles: 4000 \n" \
+ "*ncolors: 64 \n" \
+ "*fpsSolid: true \n" \
+
+# define SMOOTH_COLORS
+# define release_mountain 0
+# define reshape_mountain 0
+# define mountain_handle_event 0
+# include "xlockmore.h" /* in xscreensaver distribution */
+#else /* STANDALONE */
+# include "xlock.h" /* in xlockmore distribution */
+#endif /* STANDALONE */
+
+#ifdef MODE_mountain
+
+ENTRYPOINT ModeSpecOpt mountain_opts =
+{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
+
+#ifdef USE_MODULES
+ModStruct mountain_description =
+{"mountain", "init_mountain", "draw_mountain", (char *) NULL,
+ "refresh_mountain", "init_mountain", "free_mountain", &mountain_opts,
+ 1000, 30, 4000, 1, 64, 1.0, "",
+ "Shows Papo's mountain range", 0, NULL};
+
+#endif
+
+/* ~ 5000 Max mountain height (1000 - 10000) */
+#define MAXHEIGHT (3 * (mp->width + mp->height))
+
+#define WORLDWIDTH 50 /* World size x * y */
+
+#define RANGE_RAND(min,max) ((min) + NRAND((max) - (min)))
+
+typedef struct {
+ int pixelmode;
+ int width;
+ int height;
+ int x, y;
+ int offset;
+ int stage;
+ int h[WORLDWIDTH][WORLDWIDTH];
+ long time; /* up time */
+ Bool wireframe;
+ Bool joke;
+ GC stippledGC;
+} mountainstruct;
+
+static mountainstruct *mountains = (mountainstruct *) NULL;
+
+static void
+spread(int (*m)[50], int x, int y)
+{
+ int x2, y2;
+ int h = m[x][y];
+
+ for (y2 = y - 1; y2 <= y + 1; y2++)
+ for (x2 = x - 1; x2 <= x + 1; x2++)
+ if (x2 >= 0 && y2 >= 0 && x2 < WORLDWIDTH && y2 < WORLDWIDTH)
+ m[x2][y2] = (m[x2][y2] + h) / 2;
+}
+
+static void
+drawamountain(ModeInfo * mi)
+{
+ Display *display = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+ GC gc = MI_GC(mi);
+ mountainstruct *mp = &mountains[MI_SCREEN(mi)];
+ int x2, y2, x3, y3, y4, y5, c = 0;
+ XPoint p[5];
+
+ if (MI_NPIXELS(mi) > 2) {
+ c = (mp->h[mp->x][mp->y] + mp->h[mp->x + 1][mp->y] +
+ mp->h[mp->x][mp->y + 1] + mp->h[mp->x + 1][mp->y + 1]) / 4;
+ c = (c / 10 + mp->offset) % MI_NPIXELS(mi);
+ }
+ x2 = mp->x * (2 * mp->width) / (3 * WORLDWIDTH);
+ y2 = mp->y * (2 * mp->height) / (3 * WORLDWIDTH);
+ p[0].x = (x2 - y2 / 2) + (mp->width / 4);
+ p[0].y = (y2 - mp->h[mp->x][mp->y]) + mp->height / 4;
+
+ x3 = (mp->x + 1) * (2 * mp->width) / (3 * WORLDWIDTH);
+ y3 = mp->y * (2 * mp->height) / (3 * WORLDWIDTH);
+ p[1].x = (x3 - y3 / 2) + (mp->width / 4);
+ p[1].y = (y3 - mp->h[mp->x + 1][mp->y]) + mp->height / 4;
+
+ y4 = (mp->y + 1) * (2 * mp->height) / (3 * WORLDWIDTH);
+ p[2].x = (x3 - y4 / 2) + (mp->width / 4);
+ p[2].y = (y4 - mp->h[mp->x + 1][mp->y + 1]) + mp->height / 4;
+
+ y5 = (mp->y + 1) * (2 * mp->height) / (3 * WORLDWIDTH);
+ p[3].x = (x2 - y5 / 2) + (mp->width / 4);
+ p[3].y = (y5 - mp->h[mp->x][mp->y + 1]) + mp->height / 4;
+
+ p[4].x = p[0].x;
+ p[4].y = p[0].y;
+
+ if (MI_NPIXELS(mi) > 2)
+ XSetForeground(display, gc, MI_PIXEL(mi, c));
+ else
+ XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
+
+ if (mp->joke) {
+ if ((Bool) (LRAND() & 1))
+ XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
+ else {
+ XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin);
+ if (!mp->pixelmode) {
+ XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
+ XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
+ }
+ }
+ } else {
+ if (mp->wireframe) {
+ XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
+ } else {
+ XFillPolygon(display, window, gc, p, 4, Complex, CoordModeOrigin);
+
+ if (!mp->pixelmode) {
+ XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
+ XDrawLines(display, window, gc, p, 5, CoordModeOrigin);
+ }
+ }
+ }
+ mp->x++;
+ if (mp->x == WORLDWIDTH - 1) {
+ mp->y++;
+ mp->x = 0;
+ }
+ if (mp->y == WORLDWIDTH - 1)
+ mp->stage++;
+}
+
+ENTRYPOINT void
+init_mountain (ModeInfo * mi)
+{
+ int i, j, x, y;
+ XGCValues gcv;
+ mountainstruct *mp;
+
+ MI_INIT (mi, mountains);
+ mp = &mountains[MI_SCREEN(mi)];
+
+ mp->width = MI_WIDTH(mi);
+ mp->height = MI_HEIGHT(mi);
+ mp->pixelmode = (mp->width + mp->height < 200);
+ mp->stage = 0;
+ mp->time = 0;
+ mp->x = mp->y = 0;
+ if (MI_IS_FULLRANDOM(mi)) {
+ mp->joke = (Bool) (NRAND(10) == 0);
+ mp->wireframe = (Bool) (LRAND() & 1);
+ } else {
+ mp->joke = False;
+ mp->wireframe = MI_IS_WIREFRAME(mi);
+ }
+
+ if (mp->stippledGC == None) {
+ gcv.foreground = MI_WHITE_PIXEL(mi);
+ gcv.background = MI_BLACK_PIXEL(mi);
+ if ((mp->stippledGC = XCreateGC(MI_DISPLAY(mi), MI_WINDOW(mi),
+ GCForeground | GCBackground, &gcv)) == None)
+ return;
+ }
+ MI_CLEARWINDOW(mi);
+
+ for (y = 0; y < (int) WORLDWIDTH; y++)
+ for (x = 0; x < (int) WORLDWIDTH; x++)
+ mp->h[x][y] = 0;
+
+ j = MI_COUNT(mi);
+ if (j < 0)
+ j = NRAND(-j) + 1;
+ for (i = 0; i < j; i++)
+ mp->h[RANGE_RAND(1, WORLDWIDTH - 1)][RANGE_RAND(1, WORLDWIDTH - 1)] =
+ NRAND(MAXHEIGHT);
+
+ for (y = 0; y < WORLDWIDTH; y++)
+ for (x = 0; x < WORLDWIDTH; x++)
+ spread(mp->h, x, y);
+
+ for (y = 0; y < WORLDWIDTH; y++)
+ for (x = 0; x < WORLDWIDTH; x++) {
+ mp->h[x][y] = mp->h[x][y] + NRAND(10) - 5;
+ if (mp->h[x][y] < 10)
+ mp->h[x][y] = 0;
+ }
+
+ if (MI_NPIXELS(mi) > 2)
+ mp->offset = NRAND(MI_NPIXELS(mi));
+ else
+ mp->offset = 0;
+}
+
+ENTRYPOINT void
+draw_mountain (ModeInfo * mi)
+{
+ mountainstruct *mp;
+
+ if (mountains == NULL)
+ return;
+ mp = &mountains[MI_SCREEN(mi)];
+ if (mp->stippledGC == NULL)
+ return;
+
+ MI_IS_DRAWN(mi) = True;
+
+ switch (mp->stage) {
+ case 0:
+ drawamountain(mi);
+ break;
+ case 1:
+ if (++mp->time > MI_CYCLES(mi))
+ mp->stage++;
+ break;
+ case 2:
+ init_mountain(mi);
+ break;
+ }
+}
+
+ENTRYPOINT void
+free_mountain (ModeInfo * mi)
+{
+ mountainstruct *mp = &mountains[MI_SCREEN(mi)];
+
+ if (mp->stippledGC)
+ XFreeGC(MI_DISPLAY(mi), mp->stippledGC);
+}
+
+#ifndef STANDALONE
+ENTRYPOINT void
+refresh_mountain(ModeInfo * mi)
+{
+ mountainstruct *mp;
+
+ if (mountains == NULL)
+ return;
+ mp = &mountains[MI_SCREEN(mi)];
+
+ MI_CLEARWINDOW(mi);
+ mp->x = 0;
+ mp->y = 0;
+}
+#endif
+
+XSCREENSAVER_MODULE ("Mountain", mountain)
+
+#endif /* MODE_mountain */