static Event* expand(Window *w, Event *e, Event *eacme) { long q0, q1, x; if(getdot(w, &q0, &q1)==0 && q0 <= e->q0 && e->q0 <= q1){ e->q0 = q0; e->q1 = q1; return e; } q0 = eval(w, "#%lud-/\\[/", e->q0); if(q0 < 0) return eacme; if(eval(w, "#%lud+/\\]/", q0) < e->q0) /* [ closes before us */ return eacme; q1 = eval(w, "#%lud+/\\]/", e->q1); if(q1 < 0) return eacme; if((x=eval(w, "#%lud-/\\[/", q1))==-1 || x > e->q1) /* ] opens after us */ return eacme; e->q0 = q0+1; e->q1 = q1; return e; }
void draw_coral(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); int npoints = 0; int i; coralstruct *cp; if (reefs == NULL) return; cp = &reefs[MI_SCREEN(mi)]; if (cp->reef == NULL) return; MI_IS_DRAWN(mi) = True; for (i = 0; i < cp->nwalkers; i++) { int x = cp->walkers[i].x; int y = cp->walkers[i].y; if (getdot(x, y)) { /* XDrawPoint(display, window, gc, x, y); */ cp->pointbuf[npoints].x = x; cp->pointbuf[npoints].y = y; npoints++; /* Mark the surrounding area as "sticky" */ setdot((x - 1), (y - 1)); setdot(x, (y - 1)); setdot((x + 1), (y - 1)); setdot((x - 1), y); setdot((x + 1), y); setdot((x - 1), (y + 1)); setdot(x, (y + 1)); setdot((x + 1), (y + 1)); cp->nwalkers--; cp->walkers[i].x = cp->walkers[cp->nwalkers].x; cp->walkers[i].y = cp->walkers[cp->nwalkers].y; if (0 == cp->nwalkers || npoints >= MAXPOINTS) { XDrawPoints(display, window, gc, cp->pointbuf, npoints, CoordModeOrigin); npoints = 0; } if (MI_NPIXELS(mi) > 2) { XSetForeground(display, gc, MI_PIXEL(mi, cp->colorindex / COLORTHRESH)); if (++cp->colorindex >= MI_NPIXELS(mi) * COLORTHRESH) cp->colorindex = 0; } else XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); if (0 == cp->nwalkers) { if (cp->pointbuf) free(cp->pointbuf); cp->pointbuf = 0; init_coral(mi); return; } } else { /* move it a notch */ switch (rand_2()) { case 0: if (1 == x) continue; cp->walkers[i].x--; break; case 1: if (cp->width - 2 == x) continue; cp->walkers[i].x++; break; case 2: if (1 == y) continue; cp->walkers[i].y--; break; default: /* case 3: */ if (cp->height - 2 == y) continue; cp->walkers[i].y++; break; } } } if (npoints > 0) { XDrawPoints(display, window, gc, cp->pointbuf, npoints, CoordModeOrigin); } }
void init_coral(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); GC gc = MI_GC(mi); coralstruct *cp; int size = MI_SIZE(mi); int i; if (reefs == NULL) { if ((reefs = (coralstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (coralstruct))) == NULL) return; } cp = &reefs[MI_SCREEN(mi)]; cp->width = MAX(MI_WIDTH(mi), 4); cp->height = MAX(MI_HEIGHT(mi), 4); cp->widthb = ((cp->width + 31) >> 5); if (cp->reef != NULL) free(cp->reef); if ((cp->reef = (unsigned int *) calloc((cp->widthb + 1) * cp->height, sizeof (unsigned int))) == NULL) { free_coral(cp); return; } if (size < -MINSIZE) cp->density = NRAND(MIN(MAXSIZE, -size) - MINSIZE + 1) + MINSIZE; else if (size < MINSIZE) cp->density = MINSIZE; else cp->density = MIN(MAXSIZE, size); cp->nwalkers = MAX((cp->width * cp->height * cp->density) / 100, 1); if (cp->walkers != NULL) free(cp->walkers); if ((cp->walkers = (XPoint *) calloc(cp->nwalkers, sizeof (XPoint))) == NULL) { free_coral(cp); return; } cp->seeds = MI_COUNT(mi); if (cp->seeds < -MINSEEDS) cp->seeds = NRAND(-cp->seeds - MINSEEDS + 1) + MINSEEDS; else if (cp->seeds < MINSEEDS) cp->seeds = MINSEEDS; MI_CLEARWINDOW(mi); if (MI_NPIXELS(mi) > 2) { cp->colorindex = NRAND(MI_NPIXELS(mi) * COLORTHRESH); XSetForeground(display, gc, MI_PIXEL(mi, cp->colorindex / COLORTHRESH)); } else XSetForeground(display, gc, MI_WHITE_PIXEL(mi)); for (i = 0; i < cp->seeds; i++) { int x, y; do { x = NRAND(cp->width); y = NRAND(cp->height); } while (getdot(x, y)); setdot((x - 1), (y - 1)); setdot(x, (y - 1)); setdot((x + 1), (y - 1)); setdot((x - 1), y); setdot(x, y); setdot((x + 1), y); setdot((x - 1), (y + 1)); setdot(x, (y + 1)); setdot((x + 1), (y + 1)); XDrawPoint(display, window, gc, x, y); } for (i = 0; i < cp->nwalkers; i++) { cp->walkers[i].x = NRAND(cp->width - 2) + 1; cp->walkers[i].y = NRAND(cp->height - 2) + 1; } if (cp->pointbuf) { free(cp->pointbuf); } if ((cp->pointbuf = (XPoint *) calloc((MAXPOINTS + 2), sizeof (XPoint))) == NULL) { free_coral(cp); return; } }