+
+static muncher *make_muncher (struct state *st)
+{
+ int logwidth;
+ XWindowAttributes xgwa;
+ muncher *m = (muncher *) malloc(sizeof(muncher));
+
+ XGetWindowAttributes(st->dpy, st->window, &xgwa);
+
+ m->mismunch = st->mismunch;
+
+ /* choose size -- power of two */
+ logwidth = (st->logminwidth +
+ (random() % (1 + st->logmaxwidth - st->logminwidth)));
+
+ m->width = 1 << logwidth;
+
+ /* draw at this location */
+ m->atX = (random() % (xgwa.width <= m->width ? 1
+ : xgwa.width - m->width));
+ m->atY = (random() % (xgwa.height <= m->width ? 1
+ : xgwa.width - m->width));
+
+ /* wrap-around by these values; no need to % as we end up doing that
+ later anyway */
+ m->kX = ((random() % 2)
+ ? (random() % m->width) : 0);
+ m->kT = ((random() % 2)
+ ? (random() % m->width) : 0);
+ m->kY = ((random() % 2)
+ ? (random() % m->width) : 0);
+
+ /* set the gravity of the munch, or rather, which direction we draw
+ stuff in. */
+ m->grav = random() % 2;
+
+ /* I like this color scheme better than random colors. */
+ switch (random() % 4) {
+ case 0:
+ m->fgc.red = random() % 65536;
+ m->fgc.blue = random() % 32768;
+ m->fgc.green = random() % 16384;
+ break;
+
+ case 1:
+ m->fgc.red = 0;
+ m->fgc.blue = random() % 65536;
+ m->fgc.green = random() % 16384;
+ break;
+
+ case 2:
+ m->fgc.red = random() % 8192;
+ m->fgc.blue = random() % 8192;
+ m->fgc.green = random() % 49152;
+ break;
+
+ case 3:
+ m->fgc.red = random() % 65536;
+ m->fgc.green = m->fgc.red;
+ m->fgc.blue = m->fgc.red;
+ break;
+ }
+
+ /* Sometimes draw a mostly-overlapping copy of the square. This
+ generates all kinds of neat blocky graphics when drawing in xor
+ mode. */
+ if (!m->mismunch || (random() % 4)) {
+ m->xshadow = 0;
+ m->yshadow = 0;
+ } else {
+ m->xshadow = (random() % (m->width/3)) - (m->width/6);
+ m->yshadow = (random() % (m->width/3)) - (m->width/6);
+ }
+
+ /* Start with a random y value -- this sort of controls the type of
+ deformities seen in the squares. */
+ m->y = random() % 256;
+
+ m->t = 0;
+
+ /*
+ Doom each square to be aborted at some random point.
+ (When doom == (width - 1), the entire square will be drawn.)
+ */
+ m->doom = (m->mismunch ? (random() % m->width) : (m->width - 1));
+ m->done = 0;
+
+ return m;