1
/* -*- Mode: C; tab-width: 4 -*-
2
* lightning --- fractal lightning bolts.
4
#if !defined( lint ) && !defined( SABER )
5
static const char sccsid[] = "@(#)lightning.c 4.00 97/01/01 xlockmore";
1
/* -*- Mode: C; tab-width: 4 -*- */
2
/* lightning --- fractal lightning bolds */
5
static const char sccsid[] = "@(#)lightning.c 5.00 2000/11/01 xlockmore";
8
/* Copyright (c) 1996 by Keith Romberg <kromberg@saxe.com>.
9
* Copyright (c) 1996 by Keith Romberg <kromberg@saxe.com>
10
11
* Permission to use, copy, modify, and distribute this software and its
11
12
* documentation for any purpose and without fee is hereby granted,
20
21
* other special, indirect and consequential damages.
22
23
* Revision History:
23
* 10-May-97: jwz@jwz.org: turned into a standalone program.
24
* 14-Jul-96: Cleaned up code.
25
* 27-Jun-96: Written and submitted by Keith Romberg <kromberg@saxe.com>.
24
* 01-Nov-2000: Allocation checks
25
* 10-May-1997: Compatible with xscreensaver
26
* 14-Jul-1996: Cleaned up code.
27
* 27-Jun-1996: Written and submitted by Keith Romberg <kromberg@saxe.com>.
29
# define PROGCLASS "Lightning"
30
# define HACK_INIT init_lightning
31
# define HACK_DRAW draw_lightning
32
# define lightning_opts xlockmore_opts
33
# define DEFAULTS "*delay: 10000 \n" \
35
# define BRIGHT_COLORS
36
# include "xlockmore.h" /* from the xscreensaver distribution */
37
#else /* !STANDALONE */
38
# include "xlock.h" /* from the xlockmore distribution */
39
#endif /* !STANDALONE */
41
ModeSpecOpt lightning_opts = {
42
0, NULL, 0, NULL, NULL };
44
/*---------------------------- defines -------------------------------*/
31
#define MODE_lightning
32
#define PROGCLASS "Lightning"
33
#define HACK_INIT init_lightning
34
#define HACK_DRAW draw_lightning
35
#define lightning_opts xlockmore_opts
36
#define DEFAULTS "*delay: 10000 \n" \
39
#include "xlockmore.h" /* in xscreensaver distribution */
40
#else /* STANDALONE */
41
#include "xlock.h" /* in xlockmore distribution */
42
#endif /* STANDALONE */
46
ModeSpecOpt lightning_opts =
47
{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
50
ModStruct lightning_description =
51
{"lightning", "init_lightning", "draw_lightning", "release_lightning",
52
"refresh_lightning", "init_lightning", (char *) NULL, &lightning_opts,
53
10000, 1, 1, 1, 64, 0.6, "",
54
"Shows Keith's fractal lightning bolts", 0, NULL};
46
58
#define BOLT_NUMBER 4
47
59
#define BOLT_ITERATION 4
113
126
static int flashing_strike(void);
114
127
static void flash_duration(int *start, int *end, int total_duration);
115
128
static void random_storm(Storm * st);
116
static void generate(XPoint A, XPoint B, int iter, XPoint * verts, int *index);
129
static void generate(XPoint A, XPoint B, int iter, XPoint * verts, int *vert_index);
117
130
static void create_fork(Fork * f, XPoint start, XPoint end, int level);
119
132
static void first_strike(Lightning bolt, ModeInfo * mi);
123
136
static void level2_strike(Lightning bolt, ModeInfo * mi);
125
138
static int storm_active(Storm * st);
126
static void update_bolt(Lightning * bolt, int time);
139
static void update_bolt(Lightning * bolt, int time_now);
127
140
static void wiggle_bolt(Lightning * bolt);
128
141
static void wiggle_line(XPoint * p, int number, int wiggle_amount);
223
generate(XPoint A, XPoint B, int iter, XPoint * verts, int *index)
236
generate(XPoint A, XPoint B, int iter, XPoint * verts, int *vert_index)
228
241
mid.y = (A.y + B.y) / 2 + NRAND(HEIGHT_VARIATION) - HEIGHT_VARIATION / 2;
231
verts[*index].x = mid.x;
232
verts[*index].y = mid.y;
244
verts[*vert_index].x = mid.x;
245
verts[*vert_index].y = mid.y;
236
generate(A, mid, iter - 1, verts, index);
237
generate(mid, B, iter - 1, verts, index);
249
generate(A, mid, iter - 1, verts, vert_index);
250
generate(mid, B, iter - 1, verts, vert_index);
240
253
/*------------------------------------------------------------------------*/
270
283
/*------------------------------------------------------------------------*/
273
update_bolt(Lightning * bolt, int time)
286
update_bolt(Lightning * bolt, int time_now)
275
288
wiggle_bolt(bolt);
276
289
if ((bolt->wiggle_amount == 0) && (bolt->wiggle_number > 2))
277
290
bolt->wiggle_number = 0;
278
if (((time % 3) == 0))
291
if (((time_now % 3) == 0))
279
292
bolt->wiggle_amount++;
281
if (((time >= bolt->delay_time) && (time < bolt->flash_begin)) ||
282
(time > bolt->flash_stop))
294
if (((time_now >= bolt->delay_time) && (time_now < bolt->flash_begin)) ||
295
(time_now > bolt->flash_stop))
283
296
bolt->visible = 1;
285
298
bolt->visible = 0;
287
if (time == bolt->delay_time)
300
if (time_now == bolt->delay_time)
288
301
bolt->strike_level = FIRST_LEVEL_STRIKE;
289
else if (time == (bolt->delay_time + 1))
302
else if (time_now == (bolt->delay_time + 1))
290
303
bolt->strike_level = LEVEL_ONE_STRIKE;
291
else if ((time > (bolt->delay_time + 1)) &&
292
(time <= (bolt->delay_time + bolt->flash_begin - 2)))
304
else if ((time_now > (bolt->delay_time + 1)) &&
305
(time_now <= (bolt->delay_time + bolt->flash_begin - 2)))
293
306
bolt->strike_level = LEVEL_TWO_STRIKE;
294
else if (time == (bolt->delay_time + bolt->flash_begin - 1))
307
else if (time_now == (bolt->delay_time + bolt->flash_begin - 1))
295
308
bolt->strike_level = LEVEL_ONE_STRIKE;
296
else if (time == (bolt->delay_time + bolt->flash_stop + 1))
309
else if (time_now == (bolt->delay_time + bolt->flash_stop + 1))
297
310
bolt->strike_level = LEVEL_ONE_STRIKE;
299
312
bolt->strike_level = LEVEL_TWO_STRIKE;
324
337
GC gc = MI_GC(mi);
327
XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
340
XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
328
341
XDrawLine(display, window, gc,
329
342
bolt.end1.x, bolt.end1.y, bolt.middle[0].x, bolt.middle[0].y);
330
343
draw_line(mi, bolt.middle, BOLT_VERTICIES, gc, 0);
375
388
if (MI_NPIXELS(mi) > 2) /* color */
376
389
XSetForeground(display, gc, MI_PIXEL(mi, st->color));
378
XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
391
XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
379
392
XDrawLine(display, window, gc,
380
393
bolt.end1.x - 1, bolt.end1.y, bolt.middle[0].x - 1, bolt.middle[0].y);
381
394
draw_line(mi, bolt.middle, BOLT_VERTICIES, gc, -1);
424
437
if (MI_NPIXELS(mi) > 2)
425
438
XSetForeground(display, gc, MI_PIXEL(mi, st->color));
427
XSetForeground(display, gc, MI_WIN_WHITE_PIXEL(mi));
440
XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
428
441
XDrawLine(display, window, gc,
429
442
bolt.end1.x - 2, bolt.end1.y, bolt.middle[0].x - 2, bolt.middle[0].y);
430
443
draw_line(mi, bolt.middle, BOLT_VERTICIES, gc, -2);
514
527
st = &Helga[MI_SCREEN(mi)];
516
st->scr_width = MI_WIN_WIDTH(mi);
517
st->scr_height = MI_WIN_HEIGHT(mi);
529
st->scr_width = MI_WIDTH(mi);
530
st->scr_height = MI_HEIGHT(mi);
519
532
st->multi_strike = setup_multi_strike();
520
533
random_storm(st);
527
540
draw_lightning(ModeInfo * mi)
529
Storm *st = &Helga[MI_SCREEN(mi)];
547
st = &Helga[MI_SCREEN(mi)];
548
MI_IS_DRAWN(mi) = True;
532
549
switch (st->stage) {
534
XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi));
551
MI_IS_DRAWN(mi) = False;
553
MI_IS_DRAWN(mi) = True;
535
555
st->color = NRAND(MI_NPIXELS(mi));
536
556
st->draw_time = 0;
537
557
if (storm_active(st))
543
563
for (i = 0; i < st->multi_strike; i++) {