1 /* biof --- 3D Bioform */
2 
3 #if 0
4 static const char sccsid[] = "@(#)biof.c	5.15 2005/02/15 xlockmore";
5 #endif
6 
7 /* Copyright (c) E. Lassauge, 2005. */
8 
9 /*
10  * Permission to use, copy, modify, and distribute this software and its
11  * documentation for any purpose and without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies and that
13  * both that copyright notice and this permission notice appear in
14  * supporting documentation.
15  *
16  * This file is provided AS IS with no warranties of any kind.  The author
17  * shall have no liability with respect to the infringement of copyrights,
18  * trade secrets or any patents by this file or any part thereof.  In no
19  * event will the author be liable for any lost revenue or profits or
20  * other special, indirect and consequential damages.
21  *
22  * The original code is from the really slick screensaver series
23  * (see below the original header)
24  *
25  * Eric Lassauge  (Feb-15-2005) <lassauge AT users.sourceforge.net>
26  *
27  * REVISION HISTORY:
28  *
29  * - Eric Lassauge  (Feb-15-2005) <lassauge AT users.sourceforge.net>
30  *   Ported the rss_glx version to xlockmore (added random color + wireframe + fps)
31  */
32 
33 /*
34  * Copyright (C) 2002  <hk@dgmr.nl>
35  * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
36  *
37  * BioF is free software; you can redistribute it and/or modify
38  * it under the terms of the GNU General Public License version 2 as
39  * published by the Free Software Foundation.
40  *
41  * BioF is distributed in the hope that it will be useful,
42  * but WITHOUT ANY WARRANTY; without even the implied warranty of
43  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44  * GNU General Public License for more details.
45  *
46  * You should have received a copy of the GNU General Public License
47  * along with this program; if not, write to the Free Software
48  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
49  */
50 
51 #ifdef STANDALONE
52 # define MODE_biof
53 # define DEFAULTS       "*delay:       25000 \n" \
54                          "*count:          4 \n" \
55                          "*showFPS:    False \n" \
56                          "*cycles:       100 \n" \
57                          "*size:        6000 \n" \
58 
59 /*                         "*preset:         5 \n" */
60 #define free_biof 0
61 #define biof_handle_event 0
62 # include "xlockmore.h"         /* from the xscreensaver distribution */
63 # include <stdio.h>
64 # include <stdlib.h>
65 # include <math.h>
66 #else /* !STANDALONE */
67 # include "xlock.h"             /* from the xlockmore distribution */
68 # include "visgl.h"
69 #endif /* !STANDALONE */
70 
71 #ifdef MODE_biof
72 /* BioF screen saver */
73 
74 #include <stdlib.h>
75 #include <GL/gl.h>
76 #include <GL/glu.h>
77 
78 #define TRIANGLES 1
79 #define SPHERES 2
80 #define BIGSPHERES 3
81 #define POINTS 4
82 #define LIGHTMAP 5
83 
84 /*#define COLOR	0.9, 0.75, 0.5 */
85 /*#define COLOR_RAND(i)	((float) (NRAND(i)) / 100.0) */
86 /*  Try to keep the same 'weight' on the components: */
87 #define COLOR_RAND(i)	((float) ( (2*i - 100) + NRAND(100 - i) ) / 100.0)
88 static float C_RED;
89 static float C_GREEN;
90 static float C_BLUE;
91 #define COLOR	C_RED, C_GREEN, C_BLUE
92 
93 static void handle_opts (ModeInfo * mi);
94 
95 static XrmOptionDescRec opts[] =
96 {
97         {(char *) "-preset",    (char *) ".biof.preset",    XrmoptionSepArg, (caddr_t)NULL},
98         {(char *) "-triangles",    (char *) ".biof.preset",    XrmoptionNoArg, (caddr_t)"1"},
99         {(char *) "-spheres",    (char *) ".biof.preset",    XrmoptionNoArg, (caddr_t)"2"},
100         {(char *) "-bigspheres",    (char *) ".biof.preset",    XrmoptionNoArg, (caddr_t)"3"},
101         {(char *) "-lightmap",    (char *) ".biof.preset",    XrmoptionNoArg, (caddr_t)"5"},
102         {(char *) "-lines",    (char *) ".biof.lines",    XrmoptionSepArg, (caddr_t)NULL},
103         {(char *) "-points",    (char *) ".biof.points",    XrmoptionSepArg, (caddr_t)NULL},
104         {(char *) "-offangle",    (char *) ".biof.offangle",    XrmoptionNoArg, (caddr_t)"True"},
105         {(char *) "+offangle",    (char *) ".biof.offangle",    XrmoptionNoArg, (caddr_t)"False"},
106 };
107 
108 static int var_preset;
109 static int var_offangle;
110 static int var_lines;
111 static int var_points;
112 
113 static argtype vars[] =
114 {
115         {(void *) & var_preset, (char *) "preset",    (char *) "Preset",    (char *) "0",    t_Int},
116         {(void *) & var_lines, (char *) "lines",    (char *) "Lines",    (char *) "0",    t_Int},
117         {(void *) & var_points, (char *) "points",    (char *) "Points",    (char *) "0",    t_Int},
118         {(void *) & var_offangle, (char *) "offangle",    (char *) "OffAngle",    (char *) "False",    t_Bool},
119 };
120 
121 static OptionStruct desc[] =
122 {
123         {(char *) "-preset num",        (char *) "preset to use [1-5]"},
124         {(char *) "-triangles",         (char *) "preset 1"},
125         {(char *) "-spheres",           (char *) "preset 2"},
126         {(char *) "-bigspheres",        (char *) "preset 3"},
127         {(char *) "-lightmap",          (char *) "preset 5"},
128         {(char *) "-lines num",         (char *) "use num lines"},
129         {(char *) "-points num",        (char *) "use num points"},
130         {(char *) "+/-offangle",        (char *) "whether to use OffAngle"},
131 };
132 
133 ENTRYPOINT ModeSpecOpt biof_opts =
134 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
135 
136 #ifdef USE_MODULES
137 ModStruct   biof_description =
138 {"biof", "init_biof", "draw_biof", "release_biof",
139  "draw_biof", "init_biof", (char *) NULL, &cage_opts,
140  10000, 800, 1, 0, 1.0, "",
141  "Shows BioF", 0, NULL};
142 
143 #endif
144 
145 typedef struct {
146 #ifdef WIN32
147 	HGLRC       glx_context;
148 #else
149 	GLXContext *glx_context;
150 #endif
151         GLint       WinH, WinW;
152 	int	    wire;
153 
154 	int NRPOINTS, NRLINES;
155 	int dGeometry;
156 	int dOffAngle;
157 	double time;
158 
159 	GLUquadricObj *shapes;
160 } biofstruct;
161 
162 static biofstruct *biof = (biofstruct *) NULL;
163 
Horn(ModeInfo * mi,int ribs,double bend,double stack,double twist,double twisttrans,double grow)164 static void Horn (ModeInfo * mi, int ribs, double bend, double stack, double twist, double twisttrans, double grow)
165 {
166 	biofstruct *bp = &biof[MI_SCREEN(mi)];
167 	int i;
168 
169 	for (i = 0; i < ribs; i++) {
170 		glPushMatrix ();
171 		glRotated (i * bend / ribs, 1, 0, 0);
172 		glTranslated (0, 0, i * stack / ribs);
173 		glTranslated (twisttrans, 0, 0);
174 		glRotated (i * twist / ribs, 0, 0, 1);
175 		glTranslated (-twisttrans, 0, 0);
176 
177 		switch (bp->dGeometry) {
178 		case TRIANGLES:
179 			glBegin (bp->wire?GL_LINE_LOOP:GL_TRIANGLES);
180 			glColor4d (COLOR, 1.0);
181 			glVertex3d (2.0, 2.0, 0.0);
182 			glColor4d (COLOR, 0.0);
183 			glVertex3d (0.0, 2.0, 0.0);
184 			glVertex3d (2.0, 0.0, 0.0);
185 			glEnd ();
186 
187 			break;
188 
189 		case BIGSPHERES:
190 			if (!bp->wire)
191 			{
192 				gluQuadricDrawStyle (bp->shapes, GLU_FILL);
193 				gluQuadricNormals (bp->shapes, GLU_SMOOTH);
194 			}
195 			else
196 			{
197 				gluQuadricDrawStyle (bp->shapes, GLU_LINE);
198 				gluQuadricNormals (bp->shapes, GLU_NONE);
199 			}
200 			gluSphere (bp->shapes, 7 * exp (i / ribs * log (grow)), 20, 10);
201 
202 			break;
203 
204 		case SPHERES:
205 			if (!bp->wire)
206 			{
207 				gluQuadricDrawStyle (bp->shapes, GLU_FILL);
208 				gluQuadricNormals (bp->shapes, GLU_SMOOTH);
209 			}
210 			else
211 			{
212 				gluQuadricDrawStyle (bp->shapes, GLU_LINE);
213 				gluQuadricNormals (bp->shapes, GLU_NONE);
214 			}
215 			/*gluSphere(bp->shapes, power(grow,i/ribs), 5, 5);*/
216 			gluSphere (bp->shapes, exp (i / ribs * log (grow)), 6, 4);
217 
218 			break;
219 
220 		case LIGHTMAP:
221 		case POINTS:
222 			glBegin (GL_POINTS);
223 			glVertex3d (0, 0, 0);
224 			glEnd ();
225 
226 			break;
227 		}
228 
229 		glPopMatrix ();
230 	}
231 }
232 
233 ENTRYPOINT void
reshape_biof(ModeInfo * mi,int width,int height)234 reshape_biof (ModeInfo * mi, int width, int height)
235 {
236 	biofstruct *bp = &biof[MI_SCREEN(mi)];
237 
238 	glViewport (0, 0, bp->WinW = (GLint) width, bp->WinH = (GLint) height);
239 	glMatrixMode (GL_PROJECTION);
240 	glLoadIdentity ();
241 	gluPerspective (30, (GLdouble) width / (GLdouble) height, 100, 300);
242 }
243 
244 ENTRYPOINT void
init_biof(ModeInfo * mi)245 init_biof (ModeInfo * mi)
246 {
247 	float glfLightPosition[4] = { 100.0, 100.0, 100.0, 0.0 };
248 	float glfFog[4] = { 0.0, 0.0, 0.3, 1.0 };
249 	/*float DiffuseLightColor[4] = { 1, 0.8, 0.4, 1.0 };*/
250 	float DiffuseLightColor[4] = { 1.0, 1.0, 1.0, 1.0 };
251 	int i, j;
252 	double x, y, r, d;
253 	unsigned char texbuf[64][64];
254 	int        screen = MI_SCREEN(mi);
255         biofstruct *bp;
256 
257 	MI_INIT(mi, biof);
258         bp = &biof[screen];
259 	bp->wire = MI_IS_WIREFRAME(mi);
260 	C_RED   = COLOR_RAND(90);
261 	C_GREEN = COLOR_RAND(75);
262 	C_BLUE  = COLOR_RAND(50);
263 	DiffuseLightColor[1] = COLOR_RAND(80);
264 	DiffuseLightColor[2] = COLOR_RAND(40);
265 
266 	handle_opts(mi);
267 	if (MI_IS_DEBUG(mi)) {
268                 (void) fprintf(stderr,
269                                "%s:\n\tpreset=%d\n\toffangle=%d\n\tlines=%d\n\tpoints=%d\n\twireframe=%s\n",
270                                MI_NAME(mi),
271                                bp->dGeometry,
272                                bp->dOffAngle,
273                                bp->NRLINES,
274                                bp->NRPOINTS,
275                                bp->wire ? "yes" : "no"
276                         );
277         }
278 
279         if ((bp->glx_context = init_GL(mi)) != NULL) {
280 
281 		glEnable (GL_DEPTH_TEST);
282 
283 		if (bp->wire)
284 		{
285 			glDisable (GL_BLEND);
286 		}
287 		else
288 		{
289 			glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
290 			glEnable (GL_BLEND);
291 		}
292 
293 		if ((bp->dGeometry == SPHERES) || (bp->dGeometry == BIGSPHERES)) {
294 			if (bp->wire)
295 			{
296 				glDisable (GL_CULL_FACE);
297 				glDisable (GL_LIGHTING);
298 				glDisable (GL_LIGHT0);
299 			}
300 			else
301 			{
302 				glEnable (GL_CULL_FACE);
303 				glCullFace (GL_BACK);
304 
305 				glLightfv (GL_LIGHT0, GL_POSITION, glfLightPosition);
306 				glEnable (GL_LIGHTING);
307 				glEnable (GL_LIGHT0);
308 
309 				glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLightColor);
310 			}
311 
312 			bp->shapes = gluNewQuadric ();
313 		} else if (bp->dGeometry == POINTS) {
314 			if (bp->wire)
315 			{
316 				glDisable (GL_POINT_SMOOTH);
317 				glPointSize (3.0);
318 			}
319 			else
320 			{
321 				glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
322 				glPointSize (3.0);
323 				glEnable (GL_POINT_SMOOTH);
324 
325 				glFogi (GL_FOG_MODE, GL_LINEAR);
326 				glHint (GL_FOG_HINT, GL_NICEST);
327 				glFogfv (GL_FOG_COLOR, glfFog);
328 				glFogf (GL_FOG_START, 150);
329 				glFogf (GL_FOG_END, 250);
330 				glEnable (GL_FOG);
331 			}
332 		} else if (bp->dGeometry == LIGHTMAP) { /* Can't be wired ! */
333 			r = 32;
334 
335 			memset ((void *)&texbuf, 0, 4096);
336 
337 			for (i = 0; i < 64; i++) {
338 				for (j = 0; j < 64; j++) {
339 					x = abs (i - 32);
340 					y = abs (j - 32);
341 					d = sqrt (x * x + y * y);
342 
343 					if (d < r) {
344 						d = 1 - (d / r);
345 						texbuf[i][j] = (char)(255.0f * d * d);
346 					}
347 				}
348 			}
349 
350 			gluBuild2DMipmaps (GL_TEXTURE_2D, 1, 64, 64, GL_LUMINANCE, GL_UNSIGNED_BYTE, texbuf);
351 
352 			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
353 			glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
354 		}
355 
356 		reshape_biof (mi,MI_WIDTH(mi), MI_HEIGHT(mi));
357         } else {
358                 MI_CLEARWINDOW(mi);
359         }
360 
361 }
362 
363 ENTRYPOINT void
release_biof(ModeInfo * mi)364 release_biof (ModeInfo * mi)
365 {
366 	int         screen;
367 
368         if (biof != NULL) {
369                 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
370                         biofstruct *bp = &biof[screen];
371 			if ((bp->dGeometry == SPHERES) || (bp->dGeometry == BIGSPHERES))
372 				gluDeleteQuadric(bp->shapes);
373                 }
374                 (void)free((void *)biof);
375                 biof = (biofstruct *) NULL;
376         }
377         FreeAllGL(mi);
378 }
379 
380 ENTRYPOINT void
draw_biof(ModeInfo * mi)381 draw_biof (ModeInfo * mi)
382 {
383 #ifndef WIN32
384 	struct timeval now;
385 #endif
386 	double dt = 0;
387 	biofstruct *bp = &biof[MI_SCREEN(mi)];
388 	Display    *display = MI_DISPLAY(mi);
389         Window      window = MI_WINDOW(mi);
390 
391         MI_IS_DRAWN(mi) = True;
392 
393         if (!bp->glx_context)
394                 return;
395 #ifdef WIN32
396 	wglMakeCurrent(hdc, bp->glx_context);
397 #else
398 	glXMakeCurrent(display, window, *(bp->glx_context));
399 #endif
400 #ifdef WIN32
401 	bp->time += MI_DELAY(mi) / 100000.0;
402 	dt = bp->time;
403 #else
404 	GETTIMEOFDAY (&now);
405 	dt = (now.tv_sec * 1000000 + now.tv_usec) * 0.000001;
406 #endif
407 	if (bp->dGeometry == LIGHTMAP) {
408 		int i, j, offset;
409 		float *fb_buffer;
410 		double x, y, w;
411 
412 		if ((fb_buffer = (float *) malloc(bp->NRPOINTS *
413 				bp->NRLINES * 3 * sizeof (float))) == NULL) {
414 			return;
415 		}
416 		glDisable (GL_DEPTH_TEST);
417 		glFeedbackBuffer (bp->NRPOINTS * bp->NRLINES * 3, GL_2D, fb_buffer);
418 		glRenderMode (GL_FEEDBACK);
419 
420 		glMatrixMode (GL_MODELVIEW);
421 		glPushMatrix ();
422 		glLoadIdentity ();
423 
424 		gluLookAt (200, 0, 0, 0, 0, 0, 0, 0, 1);
425 
426 		glRotated (90, 0, 1, 0);
427 		glRotated (10 * dt, 0, 0, 1);
428 
429 		glNewList (1, GL_COMPILE);
430 		Horn (mi, bp->NRPOINTS, 315 * sin (dt * 0.237), 45 /* + 20 * sin(dt * 0.133) */ , 1500 * sin (dt * 0.213), 7.5 + 2.5 * sin (dt * 0.173), 1);
431 		glEndList ();
432 
433 		if (bp->dOffAngle)
434 			glRotated (45, 1, 1, 0);
435 
436 		for (i = 0; i < bp->NRLINES; i++) {
437 			glPushMatrix ();
438 
439 			glRotated (360 * i / bp->NRLINES, 0, 0, 1);
440 			glRotated (45, 1, 0, 0);
441 			glTranslated (0, 0, 2);
442 
443 			glCallList (1);
444 
445 			glPopMatrix ();
446 		}
447 
448 		glPopMatrix ();
449 
450 		glRenderMode (GL_RENDER);
451 
452 		glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
453 
454 		glMatrixMode (GL_PROJECTION);
455 		glPushMatrix ();
456 		glLoadIdentity ();
457 
458 		glMatrixMode (GL_MODELVIEW);
459 		glPushMatrix ();
460 		glLoadIdentity ();
461 
462 		glScalef (2.0 / bp->WinW, 2.0 / bp->WinH, 1.0);
463 		glTranslatef (-0.5 * bp->WinW, -0.5 * bp->WinH, 0.0);
464 
465 		glClear (GL_COLOR_BUFFER_BIT);
466 
467 		glEnable (GL_TEXTURE_2D);
468 		glBlendFunc (GL_ONE, GL_ONE);
469 		glEnable (GL_BLEND);
470 
471 		glBegin (GL_QUADS);
472 
473 		w = bp->WinW >> 7;
474 
475 		for (j = 0; j < bp->NRPOINTS; j++) {
476 			glColor3f (0.25 - 0.15 * j / bp->NRPOINTS, 0.15 + 0.10 * j / bp->NRPOINTS, 0.06 + 0.14 * j / bp->NRPOINTS);
477 			for (i = 0; i < bp->NRLINES; i++) {
478 				offset = 3 * (i * bp->NRPOINTS + j);
479 				x = fb_buffer[offset + 1];
480 				y = fb_buffer[offset + 2];
481 
482 				glTexCoord2f (0.0, 0.0);
483 				glVertex2f (x - w, y - w);
484 
485 				glTexCoord2f (1.0, 0.0);
486 				glVertex2f (x + w, y - w);
487 
488 				glTexCoord2f (1.0, 1.0);
489 				glVertex2f (x + w, y + w);
490 
491 				glTexCoord2f (0.0, 1.0);
492 				glVertex2f (x - w, y + w);
493 			}
494 		}
495 		if (fb_buffer != NULL)
496 			free(fb_buffer);
497 		glEnd ();
498 
499 		glMatrixMode (GL_MODELVIEW);
500 		glPopMatrix ();
501 		glMatrixMode (GL_PROJECTION);
502 		glPopMatrix ();
503 	} else {
504 		int i;
505 
506 		glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
507 
508 		glMatrixMode (GL_MODELVIEW);
509 		glLoadIdentity ();
510 		gluLookAt (200, 0, 0, 0, 0, 0, 0, 0, 1);
511 
512 		glPushMatrix ();
513 		glRotated (90, 0, 1, 0);
514 		glRotated (10 * dt, 0, 0, 1);
515 
516 		glColor3d (COLOR);
517 
518 		glNewList (1, GL_COMPILE);
519 		Horn (mi, bp->NRPOINTS, 315 * sin (dt * 0.237), 50 + 20 * sin (dt * 0.133), 1500 * sin (dt * 0.213), 7.5 + 2.5 * sin (dt * 0.173), 0.6 + 0.1 * sin (dt * 0.317));
520 		glEndList ();
521 
522 		if (bp->dOffAngle)
523 			glRotated (45, 1, 1, 0);
524 
525 		for (i = 0; i < bp->NRLINES; i++) {
526 			glPushMatrix ();
527 			glRotated (360 * i / bp->NRLINES, 0, 0, 1);
528 			glRotated (45, 1, 0, 0);
529 			glTranslated (0, 0, 2);
530 			glCallList (1);
531 			glPopMatrix ();
532 		}
533 
534 		glPopMatrix ();
535 	}
536 
537         if (MI_IS_FPS(mi)) do_fps (mi);
538         glXSwapBuffers(display, window);
539 }
540 
setDefaults(ModeInfo * mi,int use_preset)541 static void setDefaults (ModeInfo *mi, int use_preset)
542 {
543 	biofstruct *bp = &biof[MI_SCREEN(mi)];
544 	bp->dGeometry = use_preset;
545 
546 	switch (use_preset) {
547 	case TRIANGLES:
548 		bp->NRPOINTS = 80;
549 		bp->NRLINES = 32;
550 
551 		break;
552 	case SPHERES:
553 		bp->NRPOINTS = 80;
554 		bp->NRLINES = 30;
555 
556 		break;
557 	case BIGSPHERES:
558 		bp->NRPOINTS = 20;
559 		bp->NRLINES = 5;
560 
561 		break;
562 	case POINTS:
563 		bp->NRPOINTS = 250;
564 		bp->NRLINES = 30;
565 
566 		break;
567 	case LIGHTMAP:
568 		bp->NRPOINTS = 150;
569 		bp->NRLINES = 20;
570 
571 		break;
572 	}
573 }
574 
handle_opts(ModeInfo * mi)575 static void handle_opts (ModeInfo * mi)
576 {
577 	biofstruct *bp = &biof[MI_SCREEN(mi)];
578 	int change_flag = 0;
579 
580 	setDefaults(mi,LIGHTMAP);
581 	bp->dOffAngle = 0;
582 
583 	if ( (var_preset > 0) && (var_preset < 6))
584 	{
585 		change_flag = 1;
586 		setDefaults (mi, var_preset);
587 	}
588 	if (var_lines > 0)
589 	{
590 		change_flag = 1;
591 		bp->NRLINES = var_lines;
592 	}
593 	if (var_points > 0)
594 	{
595 		change_flag = 1;
596 		bp->NRPOINTS = var_points;
597 	}
598 	if (var_offangle)
599 	{
600 		change_flag = 1;
601 		bp->dOffAngle = 1;
602 	}
603 
604 	if (!change_flag) {
605 		bp->dGeometry = NRAND (5) + 1;
606 		bp->dOffAngle = NRAND (2);
607 
608 		switch (bp->dGeometry) {
609 		case TRIANGLES:
610 		case SPHERES:
611 			bp->NRLINES = NRAND (7) + 2;
612 			bp->NRPOINTS = NRAND (96) + 32;
613 			break;
614 
615 		case BIGSPHERES:
616 			bp->NRLINES = NRAND (7) + 4;
617 			bp->NRPOINTS = NRAND (32) + 4;
618 			break;
619 
620 		case POINTS:
621 		case LIGHTMAP:
622 			bp->NRLINES = NRAND (32) + 4;
623 			bp->NRPOINTS = NRAND (64) + 64;
624 		}
625 	}
626 }
627 
628 XSCREENSAVER_MODULE ("Biof", biof)
629 
630 #endif /* MODE_biof */
631