117
rock_draw (rock, True);
130
rock_compute (st, rock);
131
rock_draw (st, rock, True);
120
134
else if ((random () % 40) == 0)
135
rock_reset (st, rock);
125
rock_compute (struct rock *rock)
139
rock_compute (struct state *st, struct rock *rock)
127
double factor = depths [rock->depth];
141
double factor = st->depths [rock->depth];
128
142
double rsize = rock->real_size * factor;
130
144
rock->size = (int) (rsize + 0.5);
131
145
rock->diff = (int) GETZDIFF(rock->depth);
132
rock->x = midx + (coss [rock->theta] * rock->r * factor);
133
rock->y = midy + (sins [rock->theta] * rock->r * factor);
146
rock->x = st->midx + (st->coss [rock->theta] * rock->r * factor);
147
rock->y = st->midy + (st->sins [rock->theta] * rock->r * factor);
137
151
double move_factor = (((double) MOVE_STYLE) -
138
152
(((double) rock->depth) /
139
153
(((double) (MAX_DEPTH + 1)) *
140
154
((double) DEPTH_SCALE))));
141
155
/* move_factor is 0 when the rock is close, 1 when far */
142
rock->x += (((double) dep_x) * move_factor);
143
rock->y += (((double) dep_y) * move_factor);
156
rock->x += (((double) st->dep_x) * move_factor);
157
rock->y += (((double) st->dep_y) * move_factor);
148
rock_draw (rock, draw_p)
162
rock_draw (struct state *st, struct rock *rock, Bool draw_p)
153
? (threed ? erase_gc : draw_gcs[rock->color])
165
? (st->threed ? st->erase_gc : st->draw_gcs[rock->color])
156
if (rock->x <= 0 || rock->y <= 0 || rock->x >= width || rock->y >= height)
168
if (rock->x <= 0 || rock->y <= 0 || rock->x >= st->width || rock->y >= st->height)
158
170
/* this means that if a rock were to go off the screen at 12:00, but
159
171
would have been visible at 3:00, it won't come back once the observer
160
172
rotates around so that the rock would have been visible again.
167
179
if (rock->size <= 1)
171
if (draw_p) gc = threed_left_gc;
172
XDrawPoint (dpy, window, gc, rock->x - rock->diff, rock->y);
173
if (draw_p) gc = threed_right_gc;
174
XDrawPoint (dpy, window, gc, rock->x + rock->diff, rock->y);
183
if (draw_p) gc = st->threed_left_gc;
184
XDrawPoint (st->dpy, st->window, gc, rock->x - rock->diff, rock->y);
185
if (draw_p) gc = st->threed_right_gc;
186
XDrawPoint (st->dpy, st->window, gc, rock->x + rock->diff, rock->y);
178
XDrawPoint (dpy, window, gc, rock->x, rock->y);
190
XDrawPoint (st->dpy, st->window, gc, rock->x, rock->y);
181
193
else if (rock->size <= MIN_SIZE || !draw_p)
185
if (draw_p) gc = threed_left_gc;
186
XFillRectangle(dpy, window, gc,
197
if (draw_p) gc = st->threed_left_gc;
198
XFillRectangle(st->dpy, st->window, gc,
187
199
rock->x - rock->size / 2 - rock->diff,
188
200
rock->y - rock->size / 2,
189
201
rock->size, rock->size);
190
if (draw_p) gc = threed_right_gc;
191
XFillRectangle(dpy, window, gc,
202
if (draw_p) gc = st->threed_right_gc;
203
XFillRectangle(st->dpy, st->window, gc,
192
204
rock->x - rock->size / 2 + rock->diff,
193
205
rock->y - rock->size / 2,
194
206
rock->size, rock->size);
198
XFillRectangle (dpy, window, gc,
210
XFillRectangle (st->dpy, st->window, gc,
199
211
rock->x - rock->size/2, rock->y - rock->size/2,
200
212
rock->size, rock->size);
203
215
else if (rock->size < MAX_SIZE)
208
XCopyPlane(dpy, pixmaps[rock->size], window, gc,
219
gc = st->threed_left_gc;
220
XCopyPlane(st->dpy, st->pixmaps[rock->size], st->window, gc,
209
221
0, 0, rock->size, rock->size,
210
222
rock->x - rock->size / 2 - rock->diff,
211
223
rock->y - rock->size / 2, 1L);
212
gc = threed_right_gc;
213
XCopyPlane(dpy, pixmaps[rock->size], window, gc,
224
gc = st->threed_right_gc;
225
XCopyPlane(st->dpy, st->pixmaps[rock->size], st->window, gc,
214
226
0, 0, rock->size, rock->size,
215
227
rock->x - rock->size / 2 + rock->diff,
216
228
rock->y - rock->size / 2, 1L);
220
XCopyPlane (dpy, pixmaps [rock->size], window, gc,
232
XCopyPlane (st->dpy, st->pixmaps [rock->size], st->window, gc,
221
233
0, 0, rock->size, rock->size,
222
234
rock->x - rock->size/2, rock->y - rock->size/2,
260
272
points [4].x = i * 0.90; points [4].y = i * 0.10;
261
273
points [5].x = i * 1.00; points [5].y = i * 0.55;
262
274
points [6].x = i * 0.45; points [6].y = i * 1.00;
263
XFillPolygon (dpy, p, fg_gc, points, 7, Nonconvex, CoordModeOrigin);
275
XFillPolygon (st->dpy, p, fg_gc, points, 7, Nonconvex, CoordModeOrigin);
265
XFreeGC (dpy, fg_gc);
266
XFreeGC (dpy, bg_gc);
277
XFreeGC (st->dpy, fg_gc);
278
XFreeGC (st->dpy, bg_gc);
271
compute_move(int axe) /* 0 for x, 1 for y */
283
compute_move(struct state *st, int axe) /* 0 for x, 1 for y */
273
static int current_dep[2] = {0, 0};
274
static int speed[2] = {0, 0};
275
static short direction[2] = {0, 0};
276
static int limit[2] = {0, 0};
282
current_dep[axe] += speed[axe]; /* We adjust the displacement */
284
if (current_dep[axe] > (int) (limit[axe] * max_dep))
287
st->move_limit[0] = st->midx;
288
st->move_limit[1] = st->midy;
290
st->move_current_dep[axe] += st->move_speed[axe]; /* We adjust the displacement */
292
if (st->move_current_dep[axe] > (int) (st->move_limit[axe] * st->max_dep))
286
if (current_dep[axe] > limit[axe])
287
current_dep[axe] = limit[axe];
294
if (st->move_current_dep[axe] > st->move_limit[axe])
295
st->move_current_dep[axe] = st->move_limit[axe];
296
st->move_direction[axe] = -1;
289
297
} /* This is when we reach the upper screen limit */
290
if (current_dep[axe] < (int) (-limit[axe] * max_dep))
298
if (st->move_current_dep[axe] < (int) (-st->move_limit[axe] * st->max_dep))
292
if (current_dep[axe] < -limit[axe])
293
current_dep[axe] = -limit[axe];
300
if (st->move_current_dep[axe] < -st->move_limit[axe])
301
st->move_current_dep[axe] = -st->move_limit[axe];
302
st->move_direction[axe] = 1;
295
303
} /* This is when we reach the lower screen limit */
296
if (direction[axe] == 1) /* We adjust the speed */
298
else if (direction[axe] == -1)
301
if (speed[axe] > MAX_DEP_SPEED)
302
speed[axe] = MAX_DEP_SPEED;
303
else if (speed[axe] < -MAX_DEP_SPEED)
304
speed[axe] = -MAX_DEP_SPEED;
306
if (move_p && !(random() % DIRECTION_CHANGE_RATE))
304
if (st->move_direction[axe] == 1) /* We adjust the speed */
305
st->move_speed[axe] += 1;
306
else if (st->move_direction[axe] == -1)
307
st->move_speed[axe] -= 1;
309
if (st->move_speed[axe] > MAX_DEP_SPEED)
310
st->move_speed[axe] = MAX_DEP_SPEED;
311
else if (st->move_speed[axe] < -MAX_DEP_SPEED)
312
st->move_speed[axe] = -MAX_DEP_SPEED;
314
if (st->move_p && !(random() % DIRECTION_CHANGE_RATE))
308
316
/* We change direction */
309
317
change = random() & 1;
312
if (direction[axe] == 0)
313
direction[axe] = change - 1; /* 0 becomes either 1 or -1 */
320
if (st->move_direction[axe] == 0)
321
st->move_direction[axe] = change - 1; /* 0 becomes either 1 or -1 */
315
direction[axe] = 0; /* -1 or 1 become 0 */
323
st->move_direction[axe] = 0; /* -1 or 1 become 0 */
318
return (current_dep[axe]);
326
return (st->move_current_dep[axe]);
330
tick_rocks (struct state *st, int d)
328
dep_x = compute_move(0);
329
dep_y = compute_move(1);
336
st->dep_x = compute_move(st, 0);
337
st->dep_y = compute_move(st, 1);
332
for (i = 0; i < nrocks; i++)
333
rock_tick (&rocks [i], d);
340
for (i = 0; i < st->nrocks; i++)
341
rock_tick (st, &st->rocks [i], d);
346
rocks_draw (Display *dpy, Window window, void *closure)
340
static int current_delta = 0; /* observer Z rotation */
341
static int window_tick = 50;
342
static int new_delta = 0;
343
static int dchange_tick = 0;
345
if (window_tick++ == 50)
347
XWindowAttributes xgwa;
348
XGetWindowAttributes (dpy, window, &xgwa);
351
height = xgwa.height;
356
if (current_delta != new_delta)
358
if (dchange_tick++ == 5)
348
struct state *st = (struct state *) closure;
349
if (st->current_delta != st->new_delta)
351
if (st->dchange_tick++ == 5)
361
if (current_delta < new_delta)
353
st->dchange_tick = 0;
354
if (st->current_delta < st->new_delta)
369
362
if (! (random() % 50))
371
new_delta = ((random() % 11) - 5);
364
st->new_delta = ((random() % 11) - 5);
372
365
if (! (random() % 10))
376
tick_rocks (current_delta);
369
tick_rocks (st, st->current_delta);
380
init_rocks (Display *d, Window w)
375
rocks_init (Display *d, Window w)
377
struct state *st = (struct state *) calloc (1, sizeof(*st));
385
381
XWindowAttributes xgwa;
389
XGetWindowAttributes (dpy, window, &xgwa);
385
XGetWindowAttributes (st->dpy, st->window, &xgwa);
387
st->width = xgwa.width;
388
st->height = xgwa.height;
389
st->midx = st->width/2;
390
st->midy = st->height/2;
390
392
cmap = xgwa.colormap;
391
delay = get_integer_resource ("delay", "Integer");
392
if (delay < 0) delay = 0;
393
speed = get_integer_resource ("speed", "Integer");
394
if (speed < 1) speed = 1;
395
if (speed > 100) speed = 100;
396
rotate_p = get_boolean_resource ("rotate", "Boolean");
397
move_p = get_boolean_resource ("move", "Boolean");
393
st->delay = get_integer_resource (st->dpy, "delay", "Integer");
394
if (st->delay < 0) st->delay = 0;
395
st->speed = get_integer_resource (st->dpy, "speed", "Integer");
396
if (st->speed < 1) st->speed = 1;
397
if (st->speed > 100) st->speed = 100;
398
st->rotate_p = get_boolean_resource (st->dpy, "rotate", "Boolean");
399
st->move_p = get_boolean_resource (st->dpy, "move", "Boolean");
401
ncolors = get_integer_resource ("colors", "Colors");
403
st->ncolors = get_integer_resource (st->dpy, "colors", "Colors");
409
colors = (XColor *) malloc(ncolors * sizeof(*colors));
410
draw_gcs = (GC *) malloc(ncolors * sizeof(*draw_gcs));
412
bg = get_pixel_resource ("background", "Background", dpy, cmap);
413
colors[0].pixel = bg;
414
colors[0].flags = DoRed|DoGreen|DoBlue;
415
XQueryColor(dpy, cmap, &colors[0]);
418
make_random_colormap(dpy, xgwa.visual, cmap, colors+1, &ncolors, True,
411
st->colors = (XColor *) malloc(st->ncolors * sizeof(*st->colors));
412
st->draw_gcs = (GC *) malloc(st->ncolors * sizeof(*st->draw_gcs));
414
bg = get_pixel_resource (st->dpy, cmap, "background", "Background");
415
st->colors[0].pixel = bg;
416
st->colors[0].flags = DoRed|DoGreen|DoBlue;
417
XQueryColor(st->dpy, cmap, &st->colors[0]);
420
make_random_colormap(st->dpy, xgwa.visual, cmap, st->colors+1, &st->ncolors, True,
430
unsigned int fg = get_pixel_resource("foreground", "Foreground",
432
colors[1].pixel = fg;
433
colors[1].flags = DoRed|DoGreen|DoBlue;
434
XQueryColor(dpy, cmap, &colors[1]);
432
unsigned int fg = get_pixel_resource(st->dpy, cmap, "foreground", "Foreground");
433
st->colors[1].pixel = fg;
434
st->colors[1].flags = DoRed|DoGreen|DoBlue;
435
XQueryColor(st->dpy, cmap, &st->colors[1]);
435
436
gcv.foreground = fg;
436
437
gcv.background = bg;
437
draw_gcs[0] = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
438
draw_gcs[1] = draw_gcs[0];
438
st->draw_gcs[0] = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
439
st->draw_gcs[1] = st->draw_gcs[0];
441
for( i = 0; i < ncolors; i++ )
442
for( i = 0; i < st->ncolors; i++ )
443
gcv.foreground = colors[i].pixel;
444
gcv.foreground = st->colors[i].pixel;
444
445
gcv.background = bg;
445
draw_gcs[i] = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
446
st->draw_gcs[i] = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
448
449
gcv.foreground = bg;
449
erase_gc = XCreateGC (dpy, window, GCForeground|GCBackground, &gcv);
450
st->erase_gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground, &gcv);
451
max_dep = (move_p ? MAX_DEP : 0);
452
st->max_dep = (st->move_p ? MAX_DEP : 0);
453
454
for (i = 0; i < SIN_RESOLUTION; i++)
455
sins [i] = sin ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
456
coss [i] = cos ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
456
st->sins [i] = sin ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
457
st->coss [i] = cos ((((double) i) / (SIN_RESOLUTION / 2)) * M_PI);
458
459
/* we actually only need i/speed of these, but wtf */
459
for (i = 1; i < (sizeof (depths) / sizeof (depths[0])); i++)
460
depths [i] = atan (((double) 0.5) / (((double) i) / DEPTH_SCALE));
461
depths [0] = M_PI/2; /* avoid division by 0 */
460
for (i = 1; i < (sizeof (st->depths) / sizeof (st->depths[0])); i++)
461
st->depths [i] = atan (((double) 0.5) / (((double) i) / DEPTH_SCALE));
462
st->depths [0] = M_PI/2; /* avoid division by 0 */
463
threed = get_boolean_resource("use3d", "Boolean");
464
st->threed = get_boolean_resource(st->dpy, "use3d", "Boolean");
466
467
gcv.background = bg;
467
gcv.foreground = get_pixel_resource ("left3d", "Foreground", dpy, cmap);
468
threed_left_gc = XCreateGC (dpy, window, GCForeground|GCBackground,&gcv);
469
gcv.foreground = get_pixel_resource ("right3d", "Foreground", dpy, cmap);
470
threed_right_gc = XCreateGC (dpy, window,GCForeground|GCBackground,&gcv);
471
threed_delta = get_float_resource("delta3d", "Integer");
468
gcv.foreground = get_pixel_resource (st->dpy, cmap, "left3d", "Foreground");
469
st->threed_left_gc = XCreateGC (st->dpy, st->window, GCForeground|GCBackground,&gcv);
470
gcv.foreground = get_pixel_resource (st->dpy, cmap, "right3d", "Foreground");
471
st->threed_right_gc = XCreateGC (st->dpy, st->window,GCForeground|GCBackground,&gcv);
472
st->threed_delta = get_float_resource(st->dpy, "delta3d", "Integer");
474
475
/* don't want any exposure events from XCopyPlane */
475
for( i = 0; i < ncolors; i++)
476
XSetGraphicsExposures (dpy, draw_gcs[i], False);
477
XSetGraphicsExposures (dpy, erase_gc, False);
479
nrocks = get_integer_resource ("count", "Count");
480
if (nrocks < 1) nrocks = 1;
481
rocks = (struct rock *) calloc (nrocks, sizeof (struct rock));
482
init_pixmaps (dpy, window);
483
XClearWindow (dpy, window);
476
for( i = 0; i < st->ncolors; i++)
477
XSetGraphicsExposures (st->dpy, st->draw_gcs[i], False);
478
XSetGraphicsExposures (st->dpy, st->erase_gc, False);
480
st->nrocks = get_integer_resource (st->dpy, "count", "Count");
481
if (st->nrocks < 1) st->nrocks = 1;
482
st->rocks = (struct rock *) calloc (st->nrocks, sizeof (struct rock));
484
XClearWindow (st->dpy, st->window);
489
rocks_reshape (Display *dpy, Window window, void *closure,
490
unsigned int w, unsigned int h)
492
struct state *st = (struct state *) closure;
495
st->midx = st->width/2;
496
st->midy = st->height/2;
500
rocks_event (Display *dpy, Window window, void *closure, XEvent *event)
506
rocks_free (Display *dpy, Window window, void *closure)
488
char *progclass = "Rocks";
490
char *defaults [] = {
512
static const char *rocks_defaults [] = {
491
513
".background: Black",
492
514
".foreground: #E9967A",