ENTRYPOINT void init_antmaze(ModeInfo * mi) { double rot_speed = 0.3; int i; antmazestruct *mp; if (antmaze == NULL) { if ((antmaze = (antmazestruct *) calloc(MI_NUM_SCREENS(mi), sizeof (antmazestruct))) == NULL) return; } mp = &antmaze[MI_SCREEN(mi)]; mp->step = NRAND(90); mp->ant_position = NRAND(90); mp->antdirection[0] = PI/2.0; mp->antdirection[1] = PI/2.0; mp->antdirection[2] = 0; mp->antdirection[3] = PI/2.0; mp->antdirection[4] = PI/2.0; mp->antposition[0][0] = -4.0; mp->antposition[0][1] = 5.0; mp->antposition[0][1] = 0.15; mp->antposition[1][0] = -4.0; mp->antposition[1][1] = 3.0; mp->antposition[1][1] = 0.15; mp->antposition[2][0] = -1.0; mp->antposition[2][1] = -2.0; mp->antposition[2][1] = 0.15; mp->antposition[3][0] = -3.9; mp->antposition[3][1] = 6.0; mp->antposition[3][1] = 0.15; mp->antposition[4][0] = 2.0; mp->antposition[4][1] = -2.0; mp->antposition[4][1] = 0.15; for (i = 0; i < ANTCOUNT; i++) { mp->antvelocity[i] = 0.02; mp->antsize[i] = 1.0; mp->anton[i] = 0; } mp->bposition[0][0] = 0; mp->bposition[0][1] = 8; mp->bposition[1][0] = 9; mp->bposition[1][1] = 1; mp->bposition[2][0] = 1; mp->bposition[2][1] = 1; mp->bposition[3][0] = 4; mp->bposition[3][1] = 8; mp->bposition[4][0] = 2; mp->bposition[4][1] = 1; mp->part[0] = 0; mp->part[1] = 1; mp->part[2] = 5; mp->part[3] = 1; mp->part[4] = 3; mp->introduced = 0; mp->entroducing = 12; mp->fadeout = 1.0; mp->mag = 4.0; mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True); mp->trackball = gltrackball_init (); if ((mp->glx_context = init_GL(mi)) != NULL) { reshape_antmaze(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glDrawBuffer(GL_BACK); pinit(mp); } else MI_CLEARWINDOW(mi); }
ENTRYPOINT void init_rotor (ModeInfo * mi) { int x; elem *pelem; unsigned char wasiconified; rotorstruct *rp; if (rotors == NULL) { if ((rotors = (rotorstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (rotorstruct))) == NULL) return; } rp = &rotors[MI_SCREEN(mi)]; #ifdef HAVE_COCOA jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False); #endif rp->prevcenterx = rp->centerx; rp->prevcentery = rp->centery; rp->centerx = MI_WIDTH(mi) / 2; rp->centery = MI_HEIGHT(mi) / 2; rp->redrawing = 0; /* * sometimes, you go into iconified view, only to see a really whizzy pattern * that you would like to look more closely at. Normally, clicking in the * icon reinitializes everything - but I don't, cuz I'm that kind of guy. * HENCE, the wasiconified stuff you see here. */ wasiconified = rp->iconifiedscreen; rp->iconifiedscreen = MI_IS_ICONIC(mi); if (wasiconified && !rp->iconifiedscreen) rp->firsttime = True; else { /* This is a fudge is needed since prevcenter may not be set when it comes from the the random mode and return is pressed (and its not the first mode that was running). This assumes that the size of the lock screen window / size of the icon window = 12 */ if (!rp->prevcenterx) rp->prevcenterx = rp->centerx * 12; if (!rp->prevcentery) rp->prevcentery = rp->centery * 12; rp->num = MI_COUNT(mi); if (rp->num < 0) { rp->num = NRAND(-rp->num) + 1; if (rp->elements != NULL) { (void) free((void *) rp->elements); rp->elements = (elem *) NULL; } } if (rp->elements == NULL) if ((rp->elements = (elem *) calloc(rp->num, sizeof (elem))) == NULL) { free_rotor(rp); return; } rp->nsave = MI_CYCLES(mi); if (rp->nsave <= 1) rp->nsave = 2; if (rp->save == NULL) if ((rp->save = (XPoint *) malloc(rp->nsave * sizeof (XPoint))) == NULL) { free_rotor(rp); return; } for (x = 0; x < rp->nsave; x++) { rp->save[x].x = rp->centerx; rp->save[x].y = rp->centery; } pelem = rp->elements; for (x = rp->num; --x >= 0; pelem++) { pelem->radius_drift_max = 1.0; pelem->radius_drift_now = 1.0; pelem->end_radius = 100.0; pelem->ratio_drift_max = 1.0; pelem->ratio_drift_now = 1.0; pelem->end_ratio = 10.0; } if (MI_NPIXELS(mi) > 2) rp->pix = NRAND(MI_NPIXELS(mi)); rp->rotor = 0; rp->prev = 1; rp->lastx = rp->centerx; rp->lasty = rp->centery; rp->angle = (float) NRAND((long) MAXANGLE) / 3.0; rp->forward = rp->firsttime = True; } rp->linewidth = MI_SIZE(mi); if (rp->linewidth == 0) rp->linewidth = 1; if (rp->linewidth < 0) rp->linewidth = NRAND(-rp->linewidth) + 1; MI_CLEARWINDOW(mi); }
ENTRYPOINT void init_flow (ModeInfo * mi) { flowstruct *sp; char *name; if (flows == NULL) { if ((flows = (flowstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (flowstruct))) == NULL) return; } sp = &flows[MI_SCREEN(mi)]; sp->count2 = 0; sp->taillen = MI_SIZE(mi); if (sp->taillen < -MINTRAIL) { /* Change by sqrt so it seems more variable */ sp->taillen = NRAND((int)sqrt((double) (-sp->taillen - MINTRAIL + 1))); sp->taillen = sp->taillen * sp->taillen + MINTRAIL; } else if (sp->taillen < MINTRAIL) { sp->taillen = MINTRAIL; } if(!rotatep && !ridep) rotatep = True; /* We need at least one viewpoint */ /* Start camera at Orbit or Bee */ if(rotatep) { sp->chaseto = ORBIT; } else { sp->chaseto = BEE; } sp->chasetime = 1; /* Go directly to target */ sp->lyap = 0; sp->yperiod = 0; sp->step2 = INITIALSTEP; /* Zero parameter set */ memset(sp->par2, 0, N_PARS * sizeof(dvector)); /* Set up standard examples */ switch (NRAND((periodicp) ? 5 : 3)) { case 0: /* x' = a(y - x) y' = x(b - z) - y z' = xy - cz */ name = "Lorentz"; sp->par2[Y].x = 10 + balance_rand(5*0); /* a */ sp->par2[X].x = - sp->par2[Y].x; /* -a */ sp->par2[X].y = 28 + balance_rand(5*0); /* b */ sp->par2[XZ].y = -1; sp->par2[Y].y = -1; sp->par2[XY].z = 1; sp->par2[Z].z = - 2 + balance_rand(1*0); /* -c */ break; case 1: /* x' = -(y + az) y' = x + by z' = c + z(x - 5.7) */ name = "Rossler"; sp->par2[Y].x = -1; sp->par2[Z].x = -2 + balance_rand(1); /* a */ sp->par2[X].y = 1; sp->par2[Y].y = 0.2 + balance_rand(0.1); /* b */ sp->par2[C].z = 0.2 + balance_rand(0.1); /* c */ sp->par2[XZ].z = 1; sp->par2[Z].z = -5.7; break; case 2: /* x' = -(y + az) y' = x + by - cz^2 z' = 0.2 + z(x - 5.7) */ name = "RosslerCone"; sp->par2[Y].x = -1; sp->par2[Z].x = -2; /* a */ sp->par2[X].y = 1; sp->par2[Y].y = 0.2; /* b */ sp->par2[ZZ].y = -0.331 + balance_rand(0.01); /* c */ sp->par2[C].z = 0.2; sp->par2[XZ].z = 1; sp->par2[Z].z = -5.7; break; case 3: /* x' = -z + b sin(y) y' = c z' = 0.7x + az(0.1 - x^2) */ name = "Birkhoff"; sp->par2[Z].x = -1; sp->par2[SINY].x = 0.35 + balance_rand(0.25); /* b */ sp->par2[C].y = 1.57; /* c */ sp->par2[X].z = 0.7; sp->par2[Z].z = 1 + balance_rand(0.5); /* a/10 */ sp->par2[XXZ].z = -10 * sp->par2[Z].z; /* -a */ sp->yperiod = 2 * M_PI; break; default: /* x' = -ax - z/2 - z^3/8 + b sin(y) y' = c z' = 2x */ name = "Duffing"; sp->par2[X].x = -0.2 + balance_rand(0.1); /* a */ sp->par2[Z].x = -0.5; sp->par2[ZZZ].x = -0.125; sp->par2[SINY].x = 27.0 + balance_rand(3.0); /* b */ sp->par2[C].y = 1.33; /* c */ sp->par2[X].z = 2; sp->yperiod = 2 * M_PI; break; } sp->range.x = 5; sp->range.z = 5; if(sp->yperiod > 0) { sp->ODE = Periodic; /* periodic flows show either uniform distribution or a snapshot on the 'time' axis */ sp->range.y = NRAND(2)? sp->yperiod : 0; } else { sp->range.y = 5; sp->ODE = Cubic; } /* Run discoverer to set up bounding box, etc. Lyapunov will probably be innaccurate, since we're only running it once, but we're using known strange attractors so it should be ok. */ discover(mi); if(MI_IS_VERBOSE(mi)) fprintf(stdout, "flow: Lyapunov exponent: %g, step: %g, size: %g (%s)\n", sp->lyap2, sp->step2, sp->size2, name); /* Install new params */ sp->lyap = sp->lyap2; sp->size = sp->size2; sp->mid = sp->mid2; sp->step = sp->step2; memcpy(sp->par, sp->par2, sizeof(sp->par2)); sp->count2 = 0; /* Reset search */ free_flow(sp); sp->beecount = MI_COUNT(mi); if (sp->beecount < 0) { /* random variations */ sp->beecount = NRAND(-sp->beecount) + 1; /* Minimum 1 */ } # ifdef HAVE_COCOA /* Don't second-guess Quartz's double-buffering */ dbufp = False; # endif if(dbufp) { /* Set up double buffer */ if (sp->buffer != None) XFreePixmap(MI_DISPLAY(mi), sp->buffer); sp->buffer = XCreatePixmap(MI_DISPLAY(mi), MI_WINDOW(mi), MI_WIDTH(mi), MI_HEIGHT(mi), MI_DEPTH(mi)); } else { sp->buffer = MI_WINDOW(mi); } /* no "NoExpose" events from XCopyArea wanted */ XSetGraphicsExposures(MI_DISPLAY(mi), MI_GC(mi), False); /* Make sure we're using 'thin' lines */ XSetLineAttributes(MI_DISPLAY(mi), MI_GC(mi), 0, LineSolid, CapNotLast, JoinMiter); /* Clear the background (may be slow depending on user prefs). */ MI_CLEARWINDOW(mi); /* Allocate memory. */ if (sp->csegs == NULL) { allocate(sp->csegs, XSegment, (sp->beecount + BOX_L) * MI_NPIXELS(mi) * sp->taillen); allocate(sp->cnsegs, int, MI_NPIXELS(mi)); allocate(sp->old_segs, XSegment, sp->beecount * sp->taillen); allocate(sp->p, dvector, sp->beecount * sp->taillen); }
void init_tik_tak(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i, max_objects, size_object; tik_takstruct *tiktak; /* initialize */ if (tik_taks == NULL) { if ((tik_taks = (tik_takstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (tik_takstruct))) == NULL) return; } tiktak = &tik_taks[MI_SCREEN(mi)]; tiktak->mi = mi; if (tiktak->gc == None) { if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { XColor color; #ifndef STANDALONE tiktak->fg = MI_FG_PIXEL(mi); tiktak->bg = MI_BG_PIXEL(mi); #endif tiktak->blackpixel = MI_BLACK_PIXEL(mi); tiktak->whitepixel = MI_WHITE_PIXEL(mi); if ((tiktak->cmap = XCreateColormap(display, window, MI_VISUAL(mi), AllocNone)) == None) { free_tik_tak(display, tiktak); return; } XSetWindowColormap(display, window, tiktak->cmap); (void) XParseColor(display, tiktak->cmap, "black", &color); (void) XAllocColor(display, tiktak->cmap, &color); MI_BLACK_PIXEL(mi) = color.pixel; (void) XParseColor(display, tiktak->cmap, "white", &color); (void) XAllocColor(display, tiktak->cmap, &color); MI_WHITE_PIXEL(mi) = color.pixel; #ifndef STANDALONE (void) XParseColor(display, tiktak->cmap, background, &color); (void) XAllocColor(display, tiktak->cmap, &color); MI_BG_PIXEL(mi) = color.pixel; (void) XParseColor(display, tiktak->cmap, foreground, &color); (void) XAllocColor(display, tiktak->cmap, &color); MI_FG_PIXEL(mi) = color.pixel; #endif tiktak->colors = (XColor *) NULL; tiktak->ncolors = 0; } if ((tiktak->gc = XCreateGC(display, MI_WINDOW(mi), (unsigned long) 0, (XGCValues *) NULL)) == None) { free_tik_tak(display, tiktak); return; } } /* Clear Display */ MI_CLEARWINDOW(mi); tiktak->painted = False; XSetFunction(display, tiktak->gc, GXxor); /*Set up tik_tak data */ tiktak->direction = (LRAND() & 1) ? 1 : -1; tiktak->win_width = MI_WIDTH(mi); tiktak->win_height = MI_HEIGHT(mi); tiktak->num_object = MI_COUNT(mi); tiktak->x0 = tiktak->win_width / 2; tiktak->y0 = tiktak->win_height / 2; max_objects = MI_COUNT(mi); if (tiktak->num_object == 0) { tiktak->num_object = DEF_NUM_OBJECT; max_objects = DEF_NUM_OBJECT; } else if (tiktak->num_object < 0) { max_objects = -tiktak->num_object; tiktak->num_object = NRAND(-tiktak->num_object) + 1; } if (tiktak->object == NULL) if ((tiktak->object = (tik_takobject *) calloc(max_objects, sizeof (tik_takobject))) == NULL) { free_tik_tak(display, tiktak); return; } size_object = MIN( tiktak->win_width , tiktak->win_height) / 3; if ( abs( MI_SIZE(mi) ) > size_object) { if ( MI_SIZE( mi ) < 0 ) { size_object = -size_object; } } else { size_object = MI_SIZE(mi); } if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { /* Set up colour map */ if (tiktak->colors != NULL) { if (tiktak->ncolors && !tiktak->no_colors) free_colors(display, tiktak->cmap, tiktak->colors, tiktak->ncolors); free(tiktak->colors); tiktak->colors = (XColor *) NULL; } tiktak->ncolors = MI_NCOLORS(mi); if (tiktak->ncolors < 2) tiktak->ncolors = 2; if (tiktak->ncolors <= 2) tiktak->mono_p = True; else tiktak->mono_p = False; if (tiktak->mono_p) tiktak->colors = (XColor *) NULL; else if ((tiktak->colors = (XColor *) malloc(sizeof (*tiktak->colors) * (tiktak->ncolors + 1))) == NULL) { free_tik_tak(display, tiktak); return; } tiktak->cycle_p = has_writable_cells(mi); if (tiktak->cycle_p) { if (MI_IS_FULLRANDOM(mi)) { if (!NRAND(8)) tiktak->cycle_p = False; else tiktak->cycle_p = True; } else { tiktak->cycle_p = cycle_p; } } if (!tiktak->mono_p) { if (!(LRAND() % 10)) make_random_colormap( #ifdef STANDALONE MI_DISPLAY(mi), MI_WINDOW(mi), #else mi, #endif tiktak->cmap, tiktak->colors, &tiktak->ncolors, True, True, &tiktak->cycle_p); else if (!(LRAND() % 2)) make_uniform_colormap( #ifdef STANDALONE MI_DISPLAY(mi), MI_WINDOW(mi), #else mi, #endif tiktak->cmap, tiktak->colors, &tiktak->ncolors, True, &tiktak->cycle_p); else make_smooth_colormap( #ifdef STANDALONE MI_DISPLAY(mi), MI_WINDOW(mi), #else mi, #endif tiktak->cmap, tiktak->colors, &tiktak->ncolors, True, &tiktak->cycle_p); } XInstallColormap(display, tiktak->cmap); if (tiktak->ncolors < 2) { tiktak->ncolors = 2; tiktak->no_colors = True; } else tiktak->no_colors = False; if (tiktak->ncolors <= 2) tiktak->mono_p = True; if (tiktak->mono_p) tiktak->cycle_p = False; } for (i = 0; i < tiktak->num_object; i++) { tik_takobject *object0; object0 = &tiktak->object[i]; if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { if (tiktak->ncolors > 2) object0->colour = NRAND(tiktak->ncolors - 2) + 2; else object0->colour = 1; /* Just in case */ XSetForeground(display, tiktak->gc, tiktak->colors[object0->colour].pixel); } else { if (MI_NPIXELS(mi) > 2) object0->colour = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi))); else object0->colour = 1; /*Xor'red so WHITE may not be appropriate */ XSetForeground(display, tiktak->gc, object0->colour); } object0->angle = NRAND(90) * PI_RAD; object0->angle1 = NRAND(90) * PI_RAD; object0->velocity_a = (NRAND(7) - 3) * PI_RAD; object0->velocity_a1 = (NRAND(7) - 3) * PI_RAD; if (size_object == 0) object0->size_ob = 9; else if (size_object > 0) object0->size_ob = size_object; else object0->size_ob = NRAND(-size_object) + 1; object0->size_ob++; object0->num_point = NRAND(6)+3; if (LRAND() & 1) object0->size_mult = 1.0; else { object0->num_point *= 2; object0->size_mult = 1.0 - ( 1.0 / (float) ((LRAND() & 1) + 2 ) ); } if (object0->xy != NULL) free(object0->xy); if ((object0->xy = (XPoint *) malloc(sizeof( XPoint ) * (2 * object0->num_point + 2))) == NULL) { free_tik_tak(display, tiktak); return; } if ((LRAND() & 1) || object0->size_ob < 10 ) { object0->inner = False; if ( object0->xy1 != NULL ) free( object0->xy1 ); object0->xy1 = (XPoint *) NULL; } else { object0->inner = True; object0->size_ob1 = object0->size_ob - NRAND( object0->size_ob / 5 ) - 1; object0->num_point1 = NRAND(6)+3; if (LRAND() & 1) object0->size_mult1 = 1.0; else { object0->num_point1 *= 2; object0->size_mult1 = 1.0 - ( 1.0 / (float) ((LRAND() & 1) + 2 ) ); } if (object0->xy1 != NULL) free(object0->xy1); if ((object0->xy1 = (XPoint *) malloc(sizeof( XPoint ) * (2 * object0->num_point1 + 2))) == NULL) { free_tik_tak(display, tiktak); return; } object0->size_mult1 = 1.0; } tik_tak_setupobject( mi , object0); tik_tak_reset_object( object0); tik_tak_drawobject(mi, object0 ); } XFlush(display); XSetFunction(display, tiktak->gc, GXcopy); }
ENTRYPOINT void init_planet (ModeInfo * mi) { planetstruct *gp; int screen = MI_SCREEN(mi); Bool wire = MI_IS_WIREFRAME(mi); if (planets == NULL) { if ((planets = (planetstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (planetstruct))) == NULL) return; } gp = &planets[screen]; if ((gp->glx_context = init_GL(mi)) != NULL) { reshape_planet(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } { //char *f = get_string_resource(mi->dpy, "imageForeground", "Foreground"); //char *b = get_string_resource(mi->dpy, "imageBackground", "Background"); char *f = _strdup(imageForeground); char *b = _strdup(imageBackground); char *s; if (!f) f = _strdup("white"); if (!b) b = _strdup("black"); for (s = f + strlen(f)-1; s > f; s--) if (*s == ' ' || *s == '\t') *s = 0; for (s = b + strlen(b)-1; s > b; s--) if (*s == ' ' || *s == '\t') *s = 0; if (!XParseColor(mi->dpy, mi->xgwa.colormap, f, &gp->fg)) { fprintf(stderr, "%s: unparsable color: \"%s\"\n", progname, f); exit(1); } if (!XParseColor(mi->dpy, mi->xgwa.colormap, b, &gp->bg)) { fprintf(stderr, "%s: unparsable color: \"%s\"\n", progname, f); exit(1); } free (f); free (b); } { double spin_speed = 0.5; double wander_speed = 0.02; gp->rot = make_rotator (do_roll ? spin_speed : 0, do_roll ? spin_speed : 0, 0, 1, do_wander ? wander_speed : 0, True); gp->z = frand (1.0); gp->trackball = gltrackball_init (); } if (wire) { do_texture = False; do_light = False; } if (do_texture) setup_texture (mi); if (do_light) init_sun (mi); if (do_stars) init_stars (mi); if (random() & 1) star_spin = -star_spin; /* construct the polygons of the planet */ gp->platelist = glGenLists(1); glNewList (gp->platelist, GL_COMPILE); glColor3f (1,1,1); glPushMatrix (); glScalef (RADIUS, RADIUS, RADIUS); glRotatef (90, 1, 0, 0); glFrontFace(GL_CCW); unit_sphere (resolution, resolution, wire); glPopMatrix (); glEndList(); /* construct the polygons of the latitude/longitude/axis lines. */ gp->latlonglist = glGenLists(1); glNewList (gp->latlonglist, GL_COMPILE); glPushMatrix (); glDisable (GL_TEXTURE_2D); glDisable (GL_LIGHTING); glDisable (GL_LINE_SMOOTH); glColor3f (0.1, 0.3, 0.1); glScalef (RADIUS, RADIUS, RADIUS); glScalef (1.01, 1.01, 1.01); glRotatef (90, 1, 0, 0); unit_sphere (12, 24, 1); glBegin(GL_LINES); glVertex3f(0, -2, 0); glVertex3f(0, 2, 0); glEnd(); glPopMatrix (); glEndList(); }
ENTRYPOINT void init_laser(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); int i, c = 0; lasersstruct *lp; if (lasers == NULL) { if ((lasers = (lasersstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (lasersstruct))) == NULL) return; } lp = &lasers[MI_SCREEN(mi)]; lp->width = MI_WIDTH(mi); lp->height = MI_HEIGHT(mi); lp->time = 0; lp->ln = MI_COUNT(mi); if (lp->ln < -MINLASER) { /* if lp->ln is random ... the size can change */ if (lp->laser != NULL) { (void) free((void *) lp->laser); lp->laser = (laserstruct *) NULL; } lp->ln = NRAND(-lp->ln - MINLASER + 1) + MINLASER; } else if (lp->ln < MINLASER) lp->ln = MINLASER; if (lp->laser == NULL) { if ((lp->laser = (laserstruct *) malloc(lp->ln * sizeof (laserstruct))) == NULL) { free_laser(display, lp); return; } } if (lp->stippledGC == None) { XGCValues gcv; gcv.foreground = MI_WHITE_PIXEL(mi); gcv.background = MI_BLACK_PIXEL(mi); lp->gcv_black.foreground = MI_BLACK_PIXEL(mi); if ((lp->stippledGC = XCreateGC(display, MI_WINDOW(mi), GCForeground | GCBackground, &gcv)) == None) { free_laser(display, lp); return; } # ifdef HAVE_JWXYZ jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), lp->stippledGC, False); # endif } MI_CLEARWINDOW(mi); if (MINDIST < lp->width - MINDIST) lp->cx = RANGE_RAND(MINDIST, lp->width - MINDIST); else lp->cx = RANGE_RAND(0, lp->width); if (MINDIST < lp->height - MINDIST) lp->cy = RANGE_RAND(MINDIST, lp->height - MINDIST); else lp->cy = RANGE_RAND(0, lp->height); lp->lw = RANGE_RAND(MINWIDTH, MAXWIDTH); lp->lr = RANGE_RAND(MINREDRAW, MAXREDRAW); lp->sw = 0; lp->so = 0; if (MI_NPIXELS(mi) > 2) c = NRAND(MI_NPIXELS(mi)); for (i = 0; i < lp->ln; i++) { laserstruct *l = &lp->laser[i]; l->bn = (border) NRAND(4); switch (l->bn) { case TOP: l->bx = NRAND(lp->width); l->by = 0; break; case RIGHT: l->bx = lp->width; l->by = NRAND(lp->height); break; case BOTTOM: l->bx = NRAND(lp->width); l->by = lp->height; break; case LEFT: l->bx = 0; l->by = NRAND(lp->height); } l->dir = (int) (LRAND() & 1); l->speed = ((RANGE_RAND(MINSPEED, MAXSPEED) * lp->width) / 1000) + 1; if (MI_NPIXELS(mi) > 2) { l->gcv.foreground = MI_PIXEL(mi, c); c = (c + COLORSTEP) % MI_NPIXELS(mi); } else l->gcv.foreground = MI_WHITE_PIXEL(mi); } }
ENTRYPOINT void init_blocktube (ModeInfo *mi) { int loop; GLfloat fogColor[4] = {0,0,0,1}; blocktube_configuration *lp; int wire = MI_IS_WIREFRAME(mi); if (!lps) { lps = (blocktube_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (blocktube_configuration)); if (!lps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } lp = &lps[MI_SCREEN(mi)]; } lp = &lps[MI_SCREEN(mi)]; lp->glx_context = init_GL(mi); lp->zoom = 30; lp->tilt = 4.5; lp->tunnelLength = 200; lp->tunnelWidth = 5; if (wire) { do_fog = False; do_texture = False; glLineWidth(2); } lp->block_dlist = glGenLists (1); glNewList (lp->block_dlist, GL_COMPILE); lp->polys = cube_vertices(0.15, 1.2, 5.25, wire); glEndList (); #if defined( I_HAVE_XPM ) if (do_texture) { if (!LoadGLTextures(mi)) { fprintf(stderr, "%s: can't load textures!\n", progname); exit(1); } glEnable(GL_TEXTURE_2D); } #endif /* kick on the fog machine */ if (do_fog) { glEnable(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); glHint(GL_FOG_HINT, GL_NICEST); glFogf(GL_FOG_START, 0); glFogf(GL_FOG_END, lp->tunnelLength/1.8); glFogfv(GL_FOG_COLOR, fogColor); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); if (!do_texture && !wire) { /* If there is no texture, the boxes don't show up without a light. Though I don't understand why all the blocks come out gray. */ GLfloat pos[4] = {0.0, 1.0, 1.0, 0.0}; GLfloat amb[4] = {0.2, 0.2, 0.2, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } lp->counter = holdtime; lp->currentR = random() % 256; lp->currentG = random() % 256; lp->currentB = random() % 256; newTargetColor(lp); for (loop = 0; loop < MAX_ENTITIES; loop++) { randomize_entity(lp, &lp->entities[loop]); } reshape_blocktube(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glFlush(); }
ENTRYPOINT void init_knot (ModeInfo *mi) { knot_configuration *bp; int wire = MI_IS_WIREFRAME(mi); if (!bps) { bps = (knot_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (knot_configuration)); if (!bps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } bp = &bps[MI_SCREEN(mi)]; } bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); if (thickness <= 0) thickness = 0.001; else if (thickness > 1) thickness = 1; if (segments < 10) segments = 10; reshape_knot (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0}; GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } { Bool spinx=False, spiny=False, spinz=False; double spin_speed = 2.0; double wander_speed = 0.05; double spin_accel = 0.2; char *s = do_spin; while (*s) { if (*s == 'x' || *s == 'X') spinx = True; else if (*s == 'y' || *s == 'Y') spiny = True; else if (*s == 'z' || *s == 'Z') spinz = True; else if (*s == '0') ; else { fprintf (stderr, "%s: spin must contain only the characters X, Y, or Z (not \"%s\")\n", progname, do_spin); exit (1); } s++; } bp->rot = make_rotator (spinx ? spin_speed : 0, spiny ? spin_speed : 0, spinz ? spin_speed : 0, spin_accel, do_wander ? wander_speed : 0, (spinx && spiny && spinz)); bp->trackball = gltrackball_init (); } bp->knot_list = glGenLists (1); new_knot(mi); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
ENTRYPOINT void init_ball (ModeInfo *mi) { ball_configuration *bp; int wire = MI_IS_WIREFRAME(mi); if (!bps) { bps = (ball_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (ball_configuration)); if (!bps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_ball (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0}; GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } { double spin_speed = 10.0; double wander_speed = 0.12; double spin_accel = 2.0; bp->rot = make_rotator (do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, spin_accel, do_wander ? wander_speed : 0, True); bp->trackball = gltrackball_init (); } bp->ncolors = 128; bp->colors = (XColor *) calloc(bp->ncolors, sizeof(XColor)); make_smooth_colormap (0, 0, 0, bp->colors, &bp->ncolors, False, 0, False); bp->spikes = (int *) calloc(MI_COUNT(mi), sizeof(*bp->spikes) * 2); bp->ball_list = glGenLists (1); bp->spike_list = glGenLists (1); glNewList (bp->ball_list, GL_COMPILE); unit_sphere (SPHERE_STACKS, SPHERE_SLICES, wire); glEndList (); glNewList (bp->spike_list, GL_COMPILE); cone (0, 0, 0, 0, 1, 0, 1, 0, SPIKE_FACES, SMOOTH_SPIKES, False, wire); glEndList (); randomize_spikes (mi); }
void init_molecule (ModeInfo *mi) { molecule_configuration *mc; int wire; #ifndef STANDALONE timeout = MI_CYCLES(mi); #endif if (!mcs) { mcs = (molecule_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (molecule_configuration)); if (!mcs) { return; } } mc = &mcs[MI_SCREEN(mi)]; if (mc->glx_context) { /* Free font stuff */ free_fonts (mi); } if ((mc->glx_context = init_GL(mi)) != NULL) { glDrawBuffer(GL_BACK); gl_init(); last = 0; reshape_molecule (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } if (!load_fonts (mi)) { release_molecule(mi); return; } if (firstcall) startup_blurb (mi); cur_wire = MI_IS_WIREFRAME(mi); wire = cur_wire; mc->rotx = FLOATRAND(1.0) * RANDSIGN(); mc->roty = FLOATRAND(1.0) * RANDSIGN(); mc->rotz = FLOATRAND(1.0) * RANDSIGN(); /* bell curve from 0-6 degrees, avg 3 */ mc->dx = (FLOATRAND(0.1) + FLOATRAND(0.1) + FLOATRAND(0.1)) / (360/2); mc->dy = (FLOATRAND(0.1) + FLOATRAND(0.1) + FLOATRAND(0.1)) / (360/2); mc->dz = (FLOATRAND(0.1) + FLOATRAND(0.1) + FLOATRAND(0.1)) / (360/2); mc->d_max = mc->dx * 8; mc->ddx = 0.00006 + FLOATRAND(0.00003); mc->ddy = 0.00006 + FLOATRAND(0.00003); mc->ddz = 0.00006 + FLOATRAND(0.00003); { char *s = do_spin; while (*s) { if (*s == 'x' || *s == 'X') mc->spin_x = 1; else if (*s == 'y' || *s == 'Y') mc->spin_y = 1; else if (*s == 'z' || *s == 'Z') mc->spin_z = 1; else { (void) fprintf (stderr, "molecule: spin must contain only the characters X, Y, or Z (not \"%s\")\n", do_spin); /* exit (1); */ } s++; } } mc->molecule_dlist = glGenLists(1); load_molecules (mi); mc->which = NRAND(mc->nmolecules); #ifdef STANDALONE mc->no_label_threshold = get_float_resource ("noLabelThreshold", "NoLabelThreshold"); mc->wireframe_threshold = get_float_resource ("wireframeThreshold", "WireframeThreshold"); #else mc->no_label_threshold = 30; mc->wireframe_threshold = 150; #endif if (wire) do_bonds = 1; }
/* Constructs the GL shapes of the current molecule */ static void build_molecule (ModeInfo *mi) { molecule_configuration *mc = &mcs[MI_SCREEN(mi)]; int wire = cur_wire; int i; molecule *m = &mc->molecules[mc->which]; if (wire) { glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glDisable(GL_DEPTH_TEST); glDisable(GL_NORMALIZE); glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); } if (!wire) set_atom_color (mi, 0, False); if (do_bonds) for (i = 0; i < m->nbonds; i++) { molecule_bond *b = &m->bonds[i]; molecule_atom *from = get_atom(m->atoms, m->natoms, b->from, MI_IS_VERBOSE(mi)); molecule_atom *to = get_atom(m->atoms, m->natoms, b->to, MI_IS_VERBOSE(mi)); if (wire) { glBegin(GL_LINES); glVertex3f(from->x, from->y, from->z); glVertex3f(to->x, to->y, to->z); glEnd(); } else { int faces = (scale_down ? TUBE_FACES_2 : TUBE_FACES); # ifdef SMOOTH_TUBE int smooth = True; # else int smooth = False; # endif GLfloat thickness = 0.07 * b->strength; GLfloat cap_size = 0.03; if (thickness > 0.3) thickness = 0.3; tube (from->x, from->y, from->z, to->x, to->y, to->z, thickness, cap_size, faces, smooth, !do_atoms, wire); } } for (i = 0; i < m->natoms; i++) { molecule_atom *a = &m->atoms[i]; int i; if (!wire && do_atoms) { GLfloat size = atom_size (a); set_atom_color (mi, a, False); sphere (a->x, a->y, a->z, size, wire); } if (do_labels) { glPushAttrib (GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT); glDisable (GL_LIGHTING); glDisable (GL_DEPTH_TEST); if (!wire) set_atom_color (mi, a, True); glRasterPos3f (a->x, a->y, a->z); { GLdouble mm[17], pm[17]; GLint vp[5]; GLdouble wx=-1, wy=-1, wz=-1; glGetDoublev (GL_MODELVIEW_MATRIX, mm); glGetDoublev (GL_PROJECTION_MATRIX, pm); glGetIntegerv (GL_VIEWPORT, vp); /* Convert 3D coordinates to window coordinates */ gluProject (a->x, a->y, a->z, mm, pm, vp, &wx, &wy, &wz); /* Fudge the window coordinates to center the string */ wx -= string_width (mc->xfont1, a->label) / 2; wy -= mc->xfont1->descent; /* Convert new window coordinates back to 3D coordinates */ gluUnProject (wx, wy, wz, mm, pm, vp, &wx, &wy, &wz); glRasterPos3f (wx, wy, wz); } for (i = 0; i < (int) strlen(a->label); i++) glCallList (mc->font1_dlist + (int)(a->label[i])); glPopAttrib(); } } if (do_bbox) draw_bounding_box (mi); if (do_titles && m->label && *m->label) print_title_string (mi, m->label, 10, MI_HEIGHT(mi) - 10, mc->xfont2->ascent + mc->xfont2->descent); }
/* Pick random starting and ending positions for the given sprite. */ static void randomize_sprite (ModeInfo *mi, sprite *sp) { int vp_w = MI_WIDTH(mi); int vp_h = MI_HEIGHT(mi); int img_w = sp->img->geom.width; int img_h = sp->img->geom.height; int min_w, max_w; double ratio = (double) img_h / img_w; if (letterbox_p) { min_w = img_w; } else { if (img_w < vp_w) min_w = vp_w; else min_w = img_w * (float) vp_h / img_h; } max_w = min_w * 100 / zoom; sp->from.w = min_w + frand ((max_w - min_w) * 0.4); sp->to.w = max_w - frand ((max_w - min_w) * 0.4); sp->from.h = sp->from.w * ratio; sp->to.h = sp->to.w * ratio; if (zoom == 100) /* only one box, and it is centered */ { sp->from.x = (sp->from.w > vp_w ? -(sp->from.w - vp_w) / 2 : (vp_w - sp->from.w) / 2); sp->from.y = (sp->from.h > vp_h ? -(sp->from.h - vp_h) / 2 : (vp_h - sp->from.h) / 2); sp->to = sp->from; } else /* position both boxes randomly */ { sp->from.x = (sp->from.w > vp_w ? -frand (sp->from.w - vp_w) : frand (vp_w - sp->from.w)); sp->from.y = (sp->from.h > vp_h ? -frand (sp->from.h - vp_h) : frand (vp_h - sp->from.h)); sp->to.x = (sp->to.w > vp_w ? -frand (sp->to.w - vp_w) : frand (vp_w - sp->to.w)); sp->to.y = (sp->to.h > vp_h ? -frand (sp->to.h - vp_h) : frand (vp_h - sp->to.h)); } if (random() & 1) { rect swap = sp->to; sp->to = sp->from; sp->from = swap; } /* Make sure the aspect ratios are within 0.001 of each other. */ { int r1 = 0.5 + (sp->from.w * 1000 / sp->from.h); int r2 = 0.5 + (sp->to.w * 1000 / sp->to.h); if (r1 < r2-1 || r1 > r2+1) { fprintf (stderr, "%s: botched aspect: %f x %f (%d) vs %f x %f (%d): %s\n", progname, sp->from.w, sp->from.h, r1, sp->to.w, sp->to.h, r2, (sp->img->title ? sp->img->title : "[null]")); abort(); } } sp->from.x /= vp_w; sp->from.y /= vp_h; sp->from.w /= vp_w; sp->from.h /= vp_h; sp->to.x /= vp_w; sp->to.y /= vp_h; sp->to.w /= vp_w; sp->to.h /= vp_h; }
/* Callback that tells us that the texture has been loaded. */ static void image_loaded_cb (const char *filename, XRectangle *geom, int image_width, int image_height, int texture_width, int texture_height, void *closure) { image *img = (image *) closure; ModeInfo *mi = img->mi; /* slideshow_state *ss = &sss[MI_SCREEN(mi)]; */ int wire = MI_IS_WIREFRAME(mi); if (wire) { img->w = MI_WIDTH (mi) * (0.5 + frand (1.0)); img->h = MI_HEIGHT (mi); img->geom.width = img->w; img->geom.height = img->h; goto DONE; } if (image_width == 0 || image_height == 0) exit (1); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); img->w = image_width; img->h = image_height; img->tw = texture_width; img->th = texture_height; img->geom = *geom; img->title = (filename ? strdup (filename) : 0); /* If the image's width doesn't come back as the width of the screen, then the image must have been scaled down (due to insufficient texture memory.) Scale up the coordinates to stretch the image to fill the window. */ if (img->w != MI_WIDTH(mi)) { double scale = (double) MI_WIDTH(mi) / img->w; img->w *= scale; img->h *= scale; img->tw *= scale; img->th *= scale; img->geom.x *= scale; img->geom.y *= scale; img->geom.width *= scale; img->geom.height *= scale; } /* xscreensaver-getimage returns paths relative to the image directory now, so leave the sub-directory part in. Unless it's an absolute path. */ if (img->title && img->title[0] == '/') { /* strip filename to part between last "/" and last ".". */ char *s = strrchr (img->title, '/'); if (s) strcpy (img->title, s+1); s = strrchr (img->title, '.'); if (s) *s = 0; } if (debug_p) fprintf (stderr, "%s: loaded img %2d: \"%s\"\n", blurb(), img->id, (img->title ? img->title : "(null)")); DONE: img->loaded_p = True; }
ENTRYPOINT void draw_antmaze(ModeInfo * mi) { double h = (GLfloat) MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); antmazestruct *mp; Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); if(!antmaze) return; mp = &antmaze[MI_SCREEN(mi)]; MI_IS_DRAWN(mi) = True; if(!mp->glx_context) return; mi->polygon_count = 0; glXMakeCurrent(display, window, *(mp->glx_context)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* first panel */ glPushMatrix(); /* h = ((GLfloat) MI_HEIGHT(mi)/2) / (3*(GLfloat)MI_WIDTH(mi)/4); */ glViewport(MI_WIDTH(mi)/32, MI_HEIGHT(mi)/8, (9*MI_WIDTH(mi))/16, 3*MI_HEIGHT(mi)/4); glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* h = (3*MI_HEIGHT(mi)/4) / (3*MI_WIDTH(mi)/4); */ gluPerspective(45, 1/h, 1, 25.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); device_rotate(mi); glPushMatrix(); /* follow focused ant */ glTranslatef(0.0, 0.0, -mp->mag - 5.0); glRotatef(20.0+5.0*sin(mp->ant_step/40.0), 1.0, 0.0, 0.0); /* glTranslatef(0.0, */ /* started ? -mag : -8.0 + 4.0*fabs(sin(ant_step/10.0)), */ /* started ? -mag : -8.0 + 4.0*fabs(sin(ant_step/10.0))); */ gltrackball_rotate(mp->trackball); glRotatef(mp->ant_step*0.6, 0.0, 1.0, 0.0); /* glRotatef(90.0, 0.0, 0.0, 1.0); */ /* glTranslatef(-antposition[0][0]-0.5, 0.0, -antposition[focus][1]); */ /*-elevator*/ /* sync */ if(!draw_antmaze_strip(mi)) { release_antmaze(mi); return; } glPopMatrix(); glPopMatrix(); h = (GLfloat) (3*MI_HEIGHT(mi)/8) / (GLfloat) (MI_WIDTH(mi)/2); /* draw overhead */ glPushMatrix(); glViewport((17*MI_WIDTH(mi))/32, MI_HEIGHT(mi)/2, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8); glMatrixMode(GL_PROJECTION); glLoadIdentity(); device_rotate(mi); gluPerspective(45, 1/h, 1, 25.0); glMatrixMode(GL_MODELVIEW); /* twist scene */ glTranslatef(0.0, 0.0, -16.0); glRotatef(60.0, 1.0, 0.0, 0.0); glRotatef(-15.0 + mp->ant_step/10.0, 0.0, 1.0, 0.0); gltrackball_rotate(mp->trackball); /* sync */ if(!draw_antmaze_strip(mi)) { release_antmaze(mi); return; } glPopMatrix(); /* draw ant display */ glPushMatrix(); glViewport((5*MI_WIDTH(mi))/8, MI_HEIGHT(mi)/8, (11*MI_WIDTH(mi))/32, 3*MI_HEIGHT(mi)/8); glMatrixMode(GL_PROJECTION); glLoadIdentity(); device_rotate(mi); gluPerspective(45, 1/h, 1, 25.0); glMatrixMode(GL_MODELVIEW); /* twist scene */ glTranslatef(0.0, 0.0, -1.6); glRotatef(30.0, 1.0, 0.0, 0.0); glRotatef(mp->ant_step, 0.0, 1.0, 0.0); glRotatef(90.0, 0.0, 0.0, 1.0); /* /\* draw ant shadow *\/ */ /* glPushMatrix(); */ /* glScalef(1.0, 0.01, 1.0); */ /* glRotatef(90.0, 0.0, 0.0, 1.0); */ /* glRotatef(90.0, 0.0, 1.0, 0.0); */ /* glDisable(GL_LIGHTING); */ /* glColor4fv(MaterialGray6); */ /* /\* slow down first ant *\/ */ /* draw_ant(MaterialGrayB, 0, 1, first_ant_step, mySphere, myCone); */ /* glPopMatrix(); */ /* draw ant body */ glEnable(GL_TEXTURE_2D); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); glBindTexture(GL_TEXTURE_2D, mp->brushedtexture); draw_ant(mi, mp, MaterialGray35, 0, 1, mp->ant_step/2.0, mySphereTex, myCone2); glDisable(GL_TEXTURE_2D); glPopMatrix(); /* /\* draw overlay *\/ */ /* glPushMatrix(); */ /* /\* go to ortho mode *\/ */ /* glViewport(MI_WIDTH(mi)/2, MI_HEIGHT(mi)/8, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8); */ /* glMatrixMode(GL_PROJECTION); */ /* glLoadIdentity(); */ /* glPushMatrix (); */ /* glOrtho(-4.0, 4.0, -3.0, 3.0, -100.0, 100.0); */ /* glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGrayB); */ /* glColor4fv(MaterialGrayB); */ /* glDisable(GL_LIGHTING); */ /* glEnable(GL_BLEND); */ /* glBegin(GL_QUADS); */ /* glNormal3f(0.0, 0.0, 1.0); */ /* glVertex3f(4.0, 3.0, 0.0); */ /* glVertex3f(2.0, 3.0, 0.0); */ /* glVertex3f(2.0, -3.0, 0.0); */ /* glVertex3f(4.0, -3.0, 0.0); */ /* mi->polygon_count++; */ /* glEnd(); */ /* glEnable(GL_LIGHTING); */ /* glDisable(GL_BLEND); */ /* glPopMatrix(); */ /* glPopMatrix(); */ if (MI_IS_FPS(mi)) { glViewport(0, 0, MI_WIDTH(mi), MI_HEIGHT(mi)); do_fps (mi); } glFlush(); glXSwapBuffers(display, window); update_ants(mp); mp->step += 0.025; }
/* Standard reshape function */ ENTRYPOINT void reshape_pulsar(ModeInfo *mi, int width, int height) { glViewport( 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi) ); resetProjection(); }
ENTRYPOINT void init_quasicrystal (ModeInfo *mi) { quasicrystal_configuration *bp; int wire = MI_IS_WIREFRAME(mi); unsigned char *tex_data = 0; int tex_width; int i; if (!bps) { bps = (quasicrystal_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (quasicrystal_configuration)); if (!bps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_quasicrystal (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glDisable (GL_DEPTH_TEST); glEnable (GL_CULL_FACE); bp->count = MI_COUNT(mi); if (bp->count < 1) bp->count = 1; if (! wire) { unsigned char *o; tex_width = 4096; tex_data = (unsigned char *) calloc (4, tex_width); o = tex_data; for (i = 0; i < tex_width; i++) { unsigned char y = 255 * (1 + sin (i * M_PI * 2 / tex_width)) / 2; *o++ = y; *o++ = y; *o++ = y; *o++ = 255; } } bp->symmetric_p = get_boolean_resource (MI_DISPLAY (mi), "symmetry", "Symmetry"); bp->contrast = get_float_resource (MI_DISPLAY (mi), "contrast", "Contrast"); if (bp->contrast < 0 || bp->contrast > 100) { fprintf (stderr, "%s: contrast must be between 0 and 100%%.\n", progname); bp->contrast = 0; } { Bool spinp = get_boolean_resource (MI_DISPLAY (mi), "spin", "Spin"); Bool wanderp = get_boolean_resource (MI_DISPLAY (mi), "wander", "Wander"); double spin_speed = 0.01; double wander_speed = 0.0001; double spin_accel = 10.0; double scale_speed = 0.005; bp->planes = (plane *) calloc (sizeof (*bp->planes), bp->count); bp->ncolors = 256; /* ncolors affects color-cycling speed */ bp->colors = (XColor *) calloc (bp->ncolors, sizeof(XColor)); make_smooth_colormap (0, 0, 0, bp->colors, &bp->ncolors, False, 0, False); bp->ccolor = 0; for (i = 0; i < bp->count; i++) { plane *p = &bp->planes[i]; p->rot = make_rotator (0, 0, spinp ? spin_speed : 0, spin_accel, wanderp ? wander_speed : 0, True); p->rot2 = make_rotator (0, 0, 0, 0, scale_speed, True); if (! wire) { clear_gl_error(); glGenTextures (1, &p->texid); glBindTexture (GL_TEXTURE_1D, p->texid); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glTexImage1D (GL_TEXTURE_1D, 0, GL_RGBA, tex_width, 0, GL_RGBA, /* GL_UNSIGNED_BYTE, */ GL_UNSIGNED_INT_8_8_8_8_REV, tex_data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } } } if (tex_data) free (tex_data); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
ENTRYPOINT void draw_stairs (ModeInfo * mi) { stairsstruct *sp = &stairs[MI_SCREEN(mi)]; GLfloat rot = current_device_rotation(); Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); if (!sp->glx_context) return; glXMakeCurrent(display, window, *sp->glx_context); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(rot, 0, 0, 1); glTranslatef(0.0, 0.0, -10.0); if (!MI_IS_ICONIC(mi)) { glScalef(Scale4Window * sp->WindH / sp->WindW, Scale4Window, Scale4Window); } else { glScalef(Scale4Iconic * sp->WindH / sp->WindW, Scale4Iconic, Scale4Iconic); } # ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ { GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); if (rot != 0 && rot != 180 && rot != -180) glScalef (1/h, 1/h, 1/h); } # endif gltrackball_rotate (sp->trackball); glTranslatef(0, 0.5, 0); glRotatef(44.5, 1, 0, 0); glRotatef(50, 0, 1, 0); if (!sp->rotating) { if ((LRAND() % 500) == 0) sp->rotating = (LRAND() & 1) ? 1 : -1; } if (sp->rotating) { glRotatef(sp->rotating * sp->step, 0, 1, 0); if (sp->step >= 360) { sp->rotating = 0; sp->step = 0; } # ifndef DEBUG if (!sp->button_down_p) sp->step += 2; # endif /* DEBUG */ } draw_stairs_internal(mi); # ifdef DEBUG { int i, j; # ifdef DEBUG_PATH glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glBegin (GL_LINE_LOOP); # endif /* DEBUG_PATH */ for (i = 0; i < NPOSITIONS; i ++) for (j = 0; j < SPHERE_TICKS; j++) mi->polygon_count += draw_sphere(i, j); # ifdef DEBUG_PATH glEnd(); glEnable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); # endif /* DEBUG_PATH */ } #else /* !DEBUG */ mi->polygon_count += draw_sphere(sp->sphere_position, sp->sphere_tick); #endif /* !DEBUG */ if (sp->button_down_p) ; else if (++sp->sphere_tick >= SPHERE_TICKS) { sp->sphere_tick = 0; if (++sp->sphere_position >= NPOSITIONS) sp->sphere_position = 0; } glPopMatrix(); if (mi->fps_p) do_fps (mi); glFlush(); glXSwapBuffers(display, window); }
/* Create and return a new gear sized for placement next to or on top of the given parent gear (if any.) Returns 0 if out of memory. [Mostly lifted from pinion.c] */ static gear * new_gear (ModeInfo *mi, gear *parent) { gears_configuration *bp = &bps[MI_SCREEN(mi)]; gear *g = (gear *) calloc (1, sizeof (*g)); static unsigned long id = 0; /* only used in debugging output */ if (!g) return 0; g->id = ++id; /* Pick the size of the teeth. */ if (parent) /* adjascent gears need matching teeth */ { g->tooth_w = parent->tooth_w; g->tooth_h = parent->tooth_h; g->tooth_slope = -parent->tooth_slope; } else /* gears that begin trains get any size they want */ { g->tooth_w = 0.007 * (1.0 + BELLRAND(4.0)); g->tooth_h = 0.005 * (1.0 + BELLRAND(8.0)); /* g->tooth_slope = ((random() % 8) ? 0 : 0.5 + BELLRAND(1)); */ } /* Pick the number of teeth, and thus, the radius. */ { double c; if (!parent || bp->ngears > 4) g->nteeth = 5 + BELLRAND (20); else g->nteeth = parent->nteeth * (0.5 + BELLRAND(2)); c = g->nteeth * g->tooth_w * 2; /* circumference = teeth + gaps */ g->r = c / (M_PI * 2); /* c = 2 pi r */ } g->thickness = g->tooth_w + frand (g->r); g->thickness2 = g->thickness * 0.7; g->thickness3 = g->thickness; /* Colorize */ g->color[0] = 0.5 + frand(0.5); g->color[1] = 0.5 + frand(0.5); g->color[2] = 0.5 + frand(0.5); g->color[3] = 1.0; g->color2[0] = g->color[0] * 0.85; g->color2[1] = g->color[1] * 0.85; g->color2[2] = g->color[2] * 0.85; g->color2[3] = g->color[3]; /* Decide on shape of gear interior: - just a ring with teeth; - that, plus a thinner in-set "plate" in the middle; - that, plus a thin raised "lip" on the inner plate; - or, a wide lip (really, a thicker third inner plate.) */ if ((random() % 10) == 0) { /* inner_r can go all the way in; there's no inset disc. */ g->inner_r = (g->r * 0.1) + frand((g->r - g->tooth_h/2) * 0.8); g->inner_r2 = 0; g->inner_r3 = 0; } else { /* inner_r doesn't go in very far; inner_r2 is an inset disc. */ g->inner_r = (g->r * 0.5) + frand((g->r - g->tooth_h) * 0.4); g->inner_r2 = (g->r * 0.1) + frand(g->inner_r * 0.5); g->inner_r3 = 0; if (g->inner_r2 > (g->r * 0.2)) { int nn = (random() % 10); if (nn <= 2) g->inner_r3 = (g->r * 0.1) + frand(g->inner_r2 * 0.2); else if (nn <= 7 && g->inner_r2 >= 0.1) g->inner_r3 = g->inner_r2 - 0.01; } } /* If we have three discs, sometimes make the middle disc be spokes. */ if (g->inner_r3 && ((random() % 5) == 0)) { g->spokes = 2 + BELLRAND (5); g->spoke_thickness = 1 + frand(7.0); if (g->spokes == 2 && g->spoke_thickness < 2) g->spoke_thickness += 1; } /* Sometimes add little nubbly bits, if there is room. */ if (g->nteeth > 5) { double size = 0; involute_biggest_ring (g, 0, &size, 0); if (size > g->r * 0.2 && (random() % 5) == 0) { g->nubs = 1 + (random() % 16); if (g->nubs > 8) g->nubs = 1; } } if (g->inner_r3 > g->inner_r2) abort(); if (g->inner_r2 > g->inner_r) abort(); if (g->inner_r > g->r) abort(); /* Decide how complex the polygon model should be. */ { double pix = g->tooth_h * MI_HEIGHT(mi); /* approx. tooth size in pixels */ if (pix <= 2.5) g->size = INVOLUTE_SMALL; else if (pix <= 3.5) g->size = INVOLUTE_MEDIUM; else g->size = INVOLUTE_LARGE; } g->base_p = !parent; return g; }
ENTRYPOINT void init_ball (ModeInfo *mi) { int wire = MI_IS_WIREFRAME(mi); blinkboxstruct *bp; MI_INIT (mi, blinkbox); bp = &blinkbox[MI_SCREEN(mi)]; if ((bp->glx_context = init_GL(mi)) != NULL) { reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glDrawBuffer(GL_BACK); } else MI_CLEARWINDOW(mi); bp->ball.d = 1; bp->bscale.wh = bscale_wh; bp->bscale.d = 0.25; bp->mo.x = 1; bp->mo.y = 1; bp->mo.z = 1; bp->moh.x = -1.0; bp->moh.y = -1.5; bp->moh.z = -1.5; bp->bpos.x = 1; bp->bpos.y = 1; bp->bpos.z = 1; bp->des_amt = 1; bp->lside.counter = MAX_COUNT; bp->rside.counter = MAX_COUNT; bp->tside.counter = MAX_COUNT; bp->bside.counter = MAX_COUNT; bp->fside.counter = MAX_COUNT; bp->aside.counter = MAX_COUNT; bp->lside.color[0] = 1; bp->rside.color[1] = 1; bp->tside.color[2] = 1; bp->bside.color[0] = 1; bp->bside.color[1] = 0.5; bp->fside.color[0] = 1; bp->fside.color[1] = 1; bp->aside.color[0] = 0.5; bp->aside.color[2] = 1; bp->lside.rot[0] = 90; bp->rside.rot[0] = 90; bp->tside.rot[0] = 90; bp->bside.rot[0] = 90; bp->fside.rot[0] = 90; bp->aside.rot[0] = 90; bp->lside.rot[2] = 1; bp->rside.rot[2] = 1; bp->tside.rot[1] = 1; bp->bside.rot[1] = 1; bp->fside.rot[3] = 1; bp->aside.rot[3] = 1; bp->lside.des_count = 1; bp->rside.des_count = 1; bp->tside.des_count = 1; bp->bside.des_count = 1; bp->fside.des_count = 1; bp->aside.des_count = 1; bp->lside.alpha_count = 1; bp->rside.alpha_count = 1; bp->tside.alpha_count = 1; bp->bside.alpha_count = 1; bp->fside.alpha_count = 1; bp->aside.alpha_count = 1; #define SPHERE_SLICES 12 /* how densely to render spheres */ #define SPHERE_STACKS 16 bp->sp = malloc(sizeof(*bp->sp)); if(bp->sp == NULL){ fprintf(stderr,"Could not allocate memory\n"); exit(1); } if( (bp->bscale.wh < 1) || (bp->bscale.wh > 8) ) { fprintf(stderr,"Boxsize out of range. Using default\n"); bp->bscale.wh = 2; } if (do_dissolve){ bp->des_amt = bp->bscale.wh / MAX_COUNT; } reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); bp->ballList = glGenLists(1); glNewList(bp->ballList, GL_COMPILE); unit_sphere (SPHERE_STACKS, SPHERE_SLICES, wire); glEndList (); bp->boxList = glGenLists(1); glNewList(bp->boxList, GL_COMPILE); unit_cube(wire); glEndList(); if (wire) return; glEnable(GL_COLOR_MATERIAL); glShadeModel(GL_SMOOTH); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_LIGHTING); glClearDepth(1); glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); glEnable(GL_LIGHT1); if (do_fade || do_blur) { glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); } }
ENTRYPOINT void init_gears (ModeInfo *mi) { gears_configuration *bp; int wire = MI_IS_WIREFRAME(mi); int i; if (!bps) { bps = (gears_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (gears_configuration)); if (!bps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_gears (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0}; GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } { double spin_speed = 0.5; double wander_speed = 0.01; double spin_accel = 0.25; bp->rot = make_rotator (do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, spin_accel, do_wander ? wander_speed : 0, True ); bp->trackball = gltrackball_init (); } if (!(random() % 8)) { planetary_gears (mi); } else { gear *g = 0; int total_gears = MI_COUNT (mi); int i; if (total_gears <= 0) total_gears = 3 + abs (BELLRAND (8) - 4); /* 3 - 7, mostly 3. */ bp->gears = (gear **) calloc (total_gears+2, sizeof(**bp->gears)); bp->ngears = 0; for (i = 0; i < total_gears; i++) g = place_new_gear (mi, g); } /* Center gears in scene. */ { GLfloat minx=99999, miny=99999, maxx=-99999, maxy=-99999; int i; for (i = 0; i < bp->ngears; i++) { gear *g = bp->gears[i]; if (g->x - g->r < minx) minx = g->x - g->r; if (g->x + g->r > maxx) maxx = g->x + g->r; if (g->y - g->r < miny) miny = g->y - g->r; if (g->y + g->r > maxy) maxy = g->y + g->r; } bp->bbox.x1 = minx; bp->bbox.y1 = miny; bp->bbox.x2 = maxx; bp->bbox.y2 = maxy; } /* Now render each gear into its display list. */ for (i = 0; i < bp->ngears; i++) { gear *g = bp->gears[i]; g->dlist = glGenLists (1); if (! g->dlist) { check_gl_error ("glGenLists"); abort(); } glNewList (g->dlist, GL_COMPILE); g->polygons += draw_involute_gear (g, wire); glEndList (); } if (bp->planetary_p) armature (mi); }
ENTRYPOINT void init_spiral(ModeInfo * mi) { spiralstruct *sp; int i; if (spirals == NULL) { if ((spirals = (spiralstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (spiralstruct))) == NULL) return; } sp = &spirals[MI_SCREEN(mi)]; #ifdef HAVE_COCOA jwxyz_XSetAntiAliasing (MI_DISPLAY(mi), MI_GC(mi), False); #endif sp->width = MI_WIDTH(mi); sp->height = MI_HEIGHT(mi); MI_CLEARWINDOW(mi); /* Init */ sp->nlength = MI_CYCLES(mi); if (!sp->traildots) if ((sp->traildots = (Traildots *) malloc(sp->nlength * sizeof (Traildots))) == NULL) { return; } /* initialize the allocated array */ for (i = 0; i < sp->nlength; i++) { sp->traildots[i].hx = 0.0; sp->traildots[i].hy = 0.0; sp->traildots[i].ha = 0.0; sp->traildots[i].hr = 0.0; } sp->redrawing = 0; /* keep the window parameters proportional */ sp->top = 10000.0; sp->bottom = 0; sp->right = (float) (sp->width) / (float) (sp->height) * (10000.0); sp->left = 0; /* assign the initial values */ sp->cx = (float) (5000.0 - NRAND(2000)) / 10000.0 * sp->right; sp->cy = (float) (5000.0 - NRAND(2000)); sp->radius = (float) (NRAND(200) + 200); sp->angle = 0.0; sp->dx = (float) (10 - NRAND(20)) * SPEED; sp->dy = (float) (10 - NRAND(20)) * SPEED; sp->dr = (float) ((NRAND(10) + 4) * (1 - (LRAND() & 1) * 2)); sp->da = (float) NRAND(360) / 7200.0 + 0.01; if (MI_NPIXELS(mi) > 2) sp->colors = (float) NRAND(MI_NPIXELS(mi)); sp->erase = 0; sp->inc = 0; sp->traildots[sp->inc].hx = sp->cx; sp->traildots[sp->inc].hy = sp->cy; sp->traildots[sp->inc].ha = sp->angle; sp->traildots[sp->inc].hr = sp->radius; sp->inc++; sp->dots = MI_COUNT(mi); if (sp->dots < -MINDOTS) sp->dots = NRAND(sp->dots - MINDOTS + 1) + MINDOTS; /* Absolute minimum */ if (sp->dots < MINDOTS) sp->dots = MINDOTS; }
ENTRYPOINT Bool klein_handle_event (ModeInfo *mi, XEvent *event) { kleinstruct *kp = &klein[MI_SCREEN(mi)]; if (event->xany.type == ButtonPress && event->xbutton.button == Button1) { kp->button_down_p = True; gltrackball_start (kp->trackball, event->xbutton.x, event->xbutton.y, MI_WIDTH (mi), MI_HEIGHT (mi)); return True; } else if (event->xany.type == ButtonRelease && event->xbutton.button == Button1) { kp->button_down_p = False; return True; } else if (event->xany.type == ButtonPress && (event->xbutton.button == Button4 || event->xbutton.button == Button5 || event->xbutton.button == Button6 || event->xbutton.button == Button7)) { gltrackball_mousewheel (kp->trackball, event->xbutton.button, 10, !!event->xbutton.state); return True; } else if (event->xany.type == MotionNotify && kp->button_down_p) { gltrackball_track (kp->trackball, event->xmotion.x, event->xmotion.y, MI_WIDTH (mi), MI_HEIGHT (mi)); return True; } return False; }
ENTRYPOINT void init_sponge (ModeInfo *mi) { sponge_configuration *sp; int wire = MI_IS_WIREFRAME(mi); if (!sps) { sps = (sponge_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (sponge_configuration)); if (!sps) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } sp = &sps[MI_SCREEN(mi)]; if ((sp->glx_context = init_GL(mi)) != NULL) { reshape_sponge (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } if (!wire) { static const GLfloat pos0[4] = {-1.0, -1.0, 1.0, 0.1}; static const GLfloat pos1[4] = { 1.0, -0.2, 0.2, 0.1}; static const GLfloat dif0[4] = {1.0, 1.0, 1.0, 1.0}; static const GLfloat dif1[4] = {1.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, pos0); glLightfv(GL_LIGHT1, GL_POSITION, pos1); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif0); glLightfv(GL_LIGHT1, GL_DIFFUSE, dif1); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); } { double spin_speed = 1.0; double wander_speed = 0.03; sp->rot = make_rotator (do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, 1.0, do_wander ? wander_speed : 0, True); sp->trackball = gltrackball_init (True); } sp->ncolors = 128; sp->colors = (XColor *) calloc(sp->ncolors, sizeof(XColor)); make_smooth_colormap (0, 0, 0, sp->colors, &sp->ncolors, False, 0, False); sp->ccolor0 = 0; sp->ccolor1 = sp->ncolors / 3; sp->ccolor2 = sp->ccolor1 * 2; sp->sponge_list0 = glGenLists (1); sp->sponge_list1 = glGenLists (1); sp->sponge_list2 = glGenLists (1); sp->draw_tick = 9999999; }
ENTRYPOINT void init_klein(ModeInfo *mi) { int screen = MI_SCREEN(mi); kleinstruct *kp; if (klein == NULL) { if ((klein = (kleinstruct *) calloc(MI_NUM_SCREENS(mi), sizeof (kleinstruct))) == NULL) return; } kp = &klein[screen]; kp->window = MI_WINDOW(mi); { double spin_speed = 1.0; double wander_speed = 0.03; kp->rot = make_rotator (do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, do_spin ? spin_speed : 0, 1.0, do_wander ? wander_speed : 0, True); kp->trackball = gltrackball_init (); } if(rand) { render = random() % MY_PRIM_LAST; kp->surface = random() % SURFACE_LAST; } else { render = MY_LINE_LOOP; kp->surface = KLEIN; } switch (render) { case MY_POINTS: kp->render = GL_POINTS; break; case MY_LINES: kp->render = GL_LINES; break; case MY_LINE_LOOP: kp->render = GL_LINE_LOOP; break; default: kp->render = GL_LINE_LOOP; } /*kp->render=GL_TRIANGLE_FAN;*/ /*kp->render=GL_POLYGON;*/ kp->du = 0.07; kp->dv = 0.07; kp->a = kp->b = 1; kp->c = 0.1; if ((kp->glx_context = init_GL(mi)) != NULL) { reshape_klein(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } else { MI_CLEARWINDOW(mi); } }
ENTRYPOINT void init_fliptext (ModeInfo *mi) { int wire = MI_IS_WIREFRAME(mi); fliptext_configuration *sc; MI_INIT(mi, scs); sc = &scs[MI_SCREEN(mi)]; sc->lines = (line **) calloc (max_lines+1, sizeof(char *)); sc->dpy = MI_DISPLAY(mi); if ((sc->glx_context = init_GL(mi)) != NULL) { reshape_fliptext (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */ } { XCharStruct e; int cw, lh, ascent, descent; sc->texfont = load_texture_font (MI_DISPLAY(mi), "font"); check_gl_error ("loading font"); texture_string_metrics (sc->texfont, "n", &e, &ascent, &descent); cw = e.width; lh = ascent + descent; sc->char_width = cw; sc->line_height = lh; } if (!wire) { glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); glEnable (GL_ALPHA_TEST); glEnable (GL_TEXTURE_2D); /* "Anistropic filtering helps for quadrilateral-angled textures. A sharper image is accomplished by interpolating and filtering multiple samples from one or more mipmaps to better approximate very distorted textures. This is the next level of filtering after trilinear filtering." */ if (strstr ((char *) glGetString(GL_EXTENSIONS), "GL_EXT_texture_filter_anisotropic")) { GLfloat anisotropic = 0.0; glGetFloatv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic); if (anisotropic >= 1.0) glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic); } } /* The default font is (by fiat) "18 points". Interpret the user's font size request relative to that. */ sc->font_scale = 3 * (font_size / 18.0); if (target_columns <= 2) target_columns = 2; /* Figure out what the wrap column should be, in font-coordinate pixels. Compute it from the given -columns value, but don't let it be wider than the screen. */ { GLfloat maxw = 110 * sc->line_height / sc->font_scale; /* magic... */ sc->font_wrap_pixels = target_columns * sc->char_width; if (sc->font_wrap_pixels > maxw || sc->font_wrap_pixels <= 0) sc->font_wrap_pixels = maxw; } sc->buf_size = target_columns * max_lines; sc->buf = (char *) calloc (1, sc->buf_size); alignment_random_p = False; if (!alignment_str || !*alignment_str || !strcasecmp(alignment_str, "left")) sc->alignment = -1; else if (!strcasecmp(alignment_str, "center") || !strcasecmp(alignment_str, "middle")) sc->alignment = 0; else if (!strcasecmp(alignment_str, "right")) sc->alignment = 1; else if (!strcasecmp(alignment_str, "random")) sc->alignment = -1, alignment_random_p = True; else { fprintf (stderr, "%s: alignment must be left/center/right/random, not \"%s\"\n", progname, alignment_str); exit (1); } sc->tc = textclient_open (sc->dpy); if (max_lines < 1) max_lines = 1; min_lines = max_lines * 0.66; if (min_lines > max_lines - 3) min_lines = max_lines - 4; if (min_lines < 1) min_lines = 1; parse_color (mi, "foreground", get_string_resource(mi->dpy, "foreground", "Foreground"), sc->color); sc->top_margin = (sc->char_width * 100); sc->bottom_margin = -sc->top_margin; reshape_fliptext (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); /* compute left/right */ }
ENTRYPOINT Bool hydrostat_handle_event (ModeInfo *mi, XEvent *event) { hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; int w = MI_WIDTH(mi); int h = MI_HEIGHT(mi); int x, y; # ifdef USE_TRACKBALL if (gltrackball_event_handler (event, bp->trackball, MI_WIDTH (mi), MI_HEIGHT (mi), &bp->button_down_p)) return True; # endif switch (event->xany.type) { case ButtonPress: case ButtonRelease: x = event->xbutton.x; y = event->xbutton.y; break; case MotionNotify: x = event->xmotion.x; y = event->xmotion.y; break; default: x = y = 0; } x -= w/2; y -= h/2; x *= 0.7; y *= 0.7; if (event->xany.type == ButtonPress) { int i; GLfloat D0 = 999999; /* This is pretty halfassed hit detection, but it works ok... */ for (i = 0; i < MI_COUNT(mi); i++) { squid *s = bp->squids[i]; GLfloat X = s->pos.x - x; GLfloat Y = s->pos.z - y; GLfloat D = sqrt(X*X + Y*Y); if (D < D0) { bp->dragging = i; D0 = D; } } if (D0 > 300) /* Too far away, missed hit */ { bp->dragging = -1; return False; } bp->squids[bp->dragging]->ratio = -3; bp->button_down_p = True; return True; } else if (event->xany.type == ButtonRelease && bp->dragging >= 0) { bp->button_down_p = False; bp->dragging = -1; return True; } else if (event->xany.type == MotionNotify && bp->dragging >= 0) { squid *s = bp->squids[bp->dragging]; s->from.x = s->to.x = s->pos.x = x; s->from.z = s->to.z = s->pos.z = y; s->from.y = s->to.y = s->pos.y; return True; } return False; }
ENTRYPOINT void init_jigglypuff(ModeInfo *mi) { jigglystruct *js; int subdivs; if(!jss) { jss = (jigglystruct*) calloc(MI_NUM_SCREENS(mi), sizeof(jigglystruct)); if(!jss) { fprintf(stderr, "%s: No..memory...must...abort..\n", progname); exit(1); } } js = &jss[MI_SCREEN(mi)]; js->do_wireframe = MI_IS_WIREFRAME(mi); # ifdef HAVE_JWZGLES js->do_wireframe = 0; /* GL_LINE unimplemented */ # endif js->shininess = shininess; subdivs = (complexity==1) ? 4 : (complexity==2) ? 5 : (complexity==3) ? 6 : 5; js->spooky = spooky << (subdivs-3); if(!parse_color(js)) { fprintf(stderr, "%s: Bad color specification: '%s'.\n", progname, color); exit(-1); } if(random_parms) randomize_parameters(js); js->angle = frand(180); js->axis = frand(M_PI); js->shape = tesselated_tetrahedron(1, subdivs, js); if(!do_tetrahedron) solid_spherify(js->shape, 1); if(js->color_style == COLOR_STYLE_CLOWNBARF) clownbarf_colorize(js->shape); calculate_parameters(js, subdivs); if((js->glx_context = init_GL(mi)) != NULL) { glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(js->glx_context)); setup_opengl(mi, js); reshape_jigglypuff(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); } else { MI_CLEARWINDOW(mi); } js->trackball = gltrackball_init(); /* _DEBUG("distance : %f\nhold : %f\nspherify : %f\ndamping : %f\ndfact : %f\n", js->stable_distance, js->hold_strength, js->spherify_strength, js->damping_velocity, js->damping_factor); _DEBUG("wire : %d\nspooky : %d\nstyle : %d\nshininess : %d\n", js->do_wireframe, js->spooky, js->color_style, js->shininess);*/ }
ENTRYPOINT void init_hydrostat (ModeInfo *mi) { int wire = MI_IS_WIREFRAME(mi); hydrostat_configuration *bp; int i; MI_INIT (mi, bps, free_hydrostat); bp = &bps[MI_SCREEN(mi)]; bp->glx_context = init_GL(mi); reshape_hydrostat (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0}; GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); if (MI_COUNT(mi) <= 0) MI_COUNT(mi) = 1; if (random() & 1) current_arg = -current_arg; if (MI_COUNT(mi) == 1 || wire) opacity_arg = 1.0; if (opacity_arg < 0.1) opacity_arg = 0.1; if (opacity_arg > 1.0) opacity_arg = 1.0; bp->squids = (squid **) calloc (MI_COUNT(mi), sizeof(*bp->squids)); for (i = 0; i < MI_COUNT(mi); i++) bp->squids[i] = make_squid (mi, i); bp->dragging = -1; if (opacity_arg < 1.0) { glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE); } # ifdef USE_TRACKBALL bp->trackball = gltrackball_init (True); # endif }
static void move_fly(ModeInfo * mi, Fly * f) { int win_width = MI_WIDTH(mi); int win_height = MI_HEIGHT(mi); int left = (f->side == FLY_SIDE_LEFT) ? -(f->width) : 0; int right = (f->side == FLY_SIDE_RIGHT) ? win_width : win_width - f->width; Bool track_p = trackmouse; int cx, cy; f->oldx = f->x; /* remember position before moving, */ f->oldy = f->y; /* for unpainting previous image */ if (track_p) { Window r, c; int rx, ry; unsigned int m; (void) XQueryPointer(MI_DISPLAY(mi), MI_WINDOW(mi), &r, &c, &rx, &ry, &cx, &cy, &m); if (cx <= 0 || cy <= 0 || cx >= MI_WIDTH(mi) - f->width - 1 || cy >= MI_HEIGHT(mi) - f->width - 1) { track_p = False; } } if (track_p) { f->x = cx; f->y = cy; return; } f->x += f->vx; /* apply x velocity */ if (f->x > right) { if (f->side == FLY_SIDE_RIGHT) { unpaint_fly(mi, f); /* went off the edge, reset */ init_fly(mi, f); } else { /* Bounce off the right edge */ f->x = 2 * (win_width - f->width) - f->x; f->vx = -f->vx + f->vx / FRICTION; } } else if (f->x < left) { if (f->side == FLY_SIDE_LEFT) { unpaint_fly(mi, f); /* went off the edge, reset */ init_fly(mi, f); } else { /* Bounce off the left edge */ f->x = -f->x; f->vx = -f->vx + f->vx / FRICTION; } } f->vy++; /* gravity, accelerate in y direction */ f->y += f->vy; /* apply y velocity */ if (f->y >= (win_height - f->height)) { /* Bounce off the bottom edge */ f->y = (win_height - f->height); f->vy = -f->vy + f->vy / FRICTION; /* every once in a while, go apeshit to clean "high lurkers" */ if (NRAND(50) == 0) { f->vy *= 4; } } else if (f->y < 0) { /* Bounce off the top edge */ f->y = -f->y; f->vy = -f->vy + f->vy / FRICTION; } /* if he settles to the bottom, move him off quick */ if (abs(f->vy) < 2) { if ((f->zero_y++) > 10) { f->vx += (f->side == FLY_SIDE_LEFT) ? -1 : 1; } } else { f->zero_y = 0; /* still bouncing */ } }
/* Create and return a new gear sized for placement next to or on top of the given parent gear (if any.) Returns 0 if out of memory. */ static gear * new_gear (ModeInfo *mi, gear *parent, Bool coaxial_p) { pinion_configuration *pp = &pps[MI_SCREEN(mi)]; gear *g = (gear *) calloc (1, sizeof (*g)); int loop_count = 0; static unsigned long id = 0; /* only used in debugging output */ if (!g) return 0; if (coaxial_p && !parent) abort(); g->id = ++id; g->coax_displacement = pp->plane_displacement; while (1) { loop_count++; if (loop_count > 1000) /* The only time we loop in here is when making a coaxial gear, and trying to pick a radius that is either significantly larger or smaller than its parent. That shouldn't be hard, so something must be really wrong if we can't do that in only a few tries. */ abort(); /* Pick the size of the teeth. */ if (parent && !coaxial_p) /* adjascent gears need matching teeth */ { g->tooth_w = parent->tooth_w; g->tooth_h = parent->tooth_h; g->thickness = parent->thickness; g->thickness2 = parent->thickness2; g->thickness3 = parent->thickness3; } else /* gears that begin trains get any size they want */ { double scale = (1.0 + BELLRAND(4.0)) * gear_size; g->tooth_w = 0.007 * scale; g->tooth_h = 0.005 * scale; g->thickness = g->tooth_h * (0.1 + BELLRAND(1.5)); g->thickness2 = g->thickness / 4; g->thickness3 = g->thickness; } /* Pick the number of teeth, and thus, the radius. */ { double c; AGAIN: g->nteeth = 3 + (random() % 97); /* from 3 to 100 teeth */ if (g->nteeth < 7 && (random() % 5) != 0) goto AGAIN; /* Let's make very small tooth-counts more rare */ c = g->nteeth * g->tooth_w * 2; /* circumference = teeth + gaps */ g->r = c / (M_PI * 2); /* c = 2 pi r */ } /* Are we done now? */ if (! coaxial_p) break; /* yes */ if (g->nteeth == parent->nteeth) continue; /* ugly */ if (g->r < parent->r * 0.6) break; /* g much smaller than parent */ if (parent->r < g->r * 0.6) break; /* g much larger than parent */ } /* g->tooth_slope = (parent ? -parent->tooth_slope : 4); */ /* Colorize */ g->color[0] = 0.5 + frand(0.5); g->color[1] = 0.5 + frand(0.5); g->color[2] = 0.5 + frand(0.5); g->color[3] = 1.0; g->color2[0] = g->color[0] * 0.85; g->color2[1] = g->color[1] * 0.85; g->color2[2] = g->color[2] * 0.85; g->color2[3] = g->color[3]; /* Decide on shape of gear interior: - just a ring with teeth; - that, plus a thinner in-set "plate" in the middle; - that, plus a thin raised "lip" on the inner plate; - or, a wide lip (really, a thicker third inner plate.) */ if ((random() % 10) == 0) { /* inner_r can go all the way in; there's no inset disc. */ g->inner_r = (g->r * 0.1) + frand((g->r - g->tooth_h/2) * 0.8); g->inner_r2 = 0; g->inner_r3 = 0; } else { /* inner_r doesn't go in very far; inner_r2 is an inset disc. */ g->inner_r = (g->r * 0.5) + frand((g->r - g->tooth_h) * 0.4); g->inner_r2 = (g->r * 0.1) + frand(g->inner_r * 0.5); g->inner_r3 = 0; if (g->inner_r2 > (g->r * 0.2)) { int nn = (random() % 10); if (nn <= 2) g->inner_r3 = (g->r * 0.1) + frand(g->inner_r2 * 0.2); else if (nn <= 7 && g->inner_r2 >= 0.1) g->inner_r3 = g->inner_r2 - 0.01; } } /* Coaxial gears need to have the same innermost hole size (for the axle.) Use whichever of the two is smaller. (Modifies parent.) */ if (coaxial_p) { double hole1 = (g->inner_r3 ? g->inner_r3 : g->inner_r2 ? g->inner_r2 : g->inner_r); double hole2 = (parent->inner_r3 ? parent->inner_r3 : parent->inner_r2 ? parent->inner_r2 : parent->inner_r); double hole = (hole1 < hole2 ? hole1 : hole2); if (hole <= 0) abort(); if (g->inner_r3) g->inner_r3 = hole; else if (g->inner_r2) g->inner_r2 = hole; else g->inner_r = hole; if (parent->inner_r3) parent->inner_r3 = hole; else if (parent->inner_r2) parent->inner_r2 = hole; else parent->inner_r = hole; } /* If we have three discs, sometimes make the middle disc be spokes. */ if (g->inner_r3 && ((random() % 5) == 0)) { g->spokes = 2 + BELLRAND (5); g->spoke_thickness = 1 + frand(7.0); if (g->spokes == 2 && g->spoke_thickness < 2) g->spoke_thickness += 1; } /* Sometimes add little nubbly bits, if there is room. */ if (g->nteeth > 5) { double size = 0; involute_biggest_ring (g, 0, &size, 0); if (size > g->r * 0.2 && (random() % 5) == 0) { g->nubs = 1 + (random() % 16); if (g->nubs > 8) g->nubs = 1; } } if (g->inner_r3 > g->inner_r2) abort(); if (g->inner_r2 > g->inner_r) abort(); if (g->inner_r > g->r) abort(); /* Decide how complex the polygon model should be. */ { double pix = g->tooth_h * MI_HEIGHT(mi); /* approx. tooth size in pixels */ if (pix <= 2.5) g->size = INVOLUTE_SMALL; else if (pix <= 3.5) g->size = INVOLUTE_MEDIUM; else g->size = INVOLUTE_LARGE; } g->base_p = !parent; return g; }