diff options
Diffstat (limited to 'hacks/mountain.c')
-rw-r--r-- | hacks/mountain.c | 282 |
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 */ |