1 /*
2  * Copyright (C) 2002  Terence M. Welsh
3  * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
4  *
5  * Euphoria is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Euphoria is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 /*
20  * Euphoria screensaver
21  */
22 
23 const char *hack_name = "euphoria";
24 
25 #include <stdio.h>
26 #include <GL/gl.h>
27 #include <GL/glu.h>
28 
29 #include "driver.h"
30 #include "euphoria_textures.h"
31 #include "loadTexture.h"
32 #include "rgbhsl.h"
33 #include "rsDefines.h"
34 #include "rsRand.h"
35 #include <rsMath/rsVec.h>
36 
37 #define PRESET_REGULAR 1
38 #define PRESET_GRID 2
39 #define PRESET_CUBISM 3
40 #define PRESET_BADMATH 4
41 #define PRESET_MTHEORY 5
42 #define PRESET_UHFTEM 6
43 #define PRESET_NOWHERE 7
44 #define PRESET_ECHO 8
45 #define PRESET_KALEIDOSCOPE 9
46 
47 #define NUMCONSTS 9
48 #define TEXSIZE 256
49 
50 typedef struct {
51 	float ***vertices;
52 	float c[NUMCONSTS];	/* constants */
53 	float cr[NUMCONSTS];	/* constants radial position */
54 	float cv[NUMCONSTS];	/* constants change velocities */
55 	float hsl[3];
56 	float rgb[3];
57 	float hueSpeed;
58 	float saturationSpeed;
59 } wisp;
60 
61 wisp *backwisps;
62 wisp *wisps;
63 unsigned int tex;
64 float aspectRatio;
65 int viewport[4];
66 float elapsedTime;
67 
68 /*
69  * Parameters edited in the dialog box
70  */
71 int dWisps;
72 int dBgWisps;
73 int dDensity;
74 int dVisibility;
75 int dSpeed;
76 int dFeedback;
77 int dFeedbackspeed;
78 int dFeedbacksize;
79 int dWireframe;
80 int dTexture;
81 int dPriority;
82 
83 /*
84  * feedback texture object
85  */
86 unsigned int feedbacktex;
87 unsigned int feedbacktexsize;
88 
89 /*
90  * feedback variables
91  */
92 float fr[4];
93 float fv[4];
94 float f[4];
95 
96 /*
97  * feedback limiters
98  */
99 float lr[3];
100 float lv[3];
101 float l[3];
102 
setDefaults(int which)103 void setDefaults (int which)
104 {
105 	switch (which) {
106 	case PRESET_REGULAR:	/* Regular */
107 		dWisps = 5;
108 		dBgWisps = 0;
109 		dDensity = 35;
110 		dVisibility = 35;
111 		dSpeed = 15;
112 		dFeedback = 0;
113 		dFeedbackspeed = 1;
114 		dFeedbacksize = 10;
115 		dWireframe = 0;
116 		dTexture = 2;
117 		break;
118 	case PRESET_GRID:	/* Grid */
119 		dWisps = 4;
120 		dBgWisps = 1;
121 		dDensity = 30;
122 		dVisibility = 70;
123 		dSpeed = 15;
124 		dFeedback = 0;
125 		dFeedbackspeed = 1;
126 		dFeedbacksize = 10;
127 		dWireframe = 1;
128 		dTexture = 0;
129 		break;
130 	case PRESET_CUBISM:	/* Cubism */
131 		dWisps = 15;
132 		dBgWisps = 0;
133 		dDensity = 4;
134 		dVisibility = 15;
135 		dSpeed = 10;
136 		dFeedback = 0;
137 		dFeedbackspeed = 1;
138 		dFeedbacksize = 10;
139 		dWireframe = 0;
140 		dTexture = 0;
141 		break;
142 	case PRESET_BADMATH:	/* Bad math */
143 		dWisps = 2;
144 		dBgWisps = 2;
145 		dDensity = 20;
146 		dVisibility = 40;
147 		dSpeed = 30;
148 		dFeedback = 40;
149 		dFeedbackspeed = 5;
150 		dFeedbacksize = 10;
151 		dWireframe = 1;
152 		dTexture = 2;
153 		break;
154 	case PRESET_MTHEORY:	/* M-Theory */
155 		dWisps = 3;
156 		dBgWisps = 0;
157 		dDensity = 35;
158 		dVisibility = 15;
159 		dSpeed = 20;
160 		dFeedback = 40;
161 		dFeedbackspeed = 20;
162 		dFeedbacksize = 10;
163 		dWireframe = 0;
164 		dTexture = 0;
165 		break;
166 	case PRESET_UHFTEM:	/* ultra high frequency tunneling electron microscope */
167 		dWisps = 0;
168 		dBgWisps = 3;
169 		dDensity = 35;
170 		dVisibility = 5;
171 		dSpeed = 50;
172 		dFeedback = 0;
173 		dFeedbackspeed = 1;
174 		dFeedbacksize = 10;
175 		dWireframe = 0;
176 		dTexture = 0;
177 		break;
178 	case PRESET_NOWHERE:	/* Nowhere */
179 		dWisps = 0;
180 		dBgWisps = 3;
181 		dDensity = 30;
182 		dVisibility = 40;
183 		dSpeed = 20;
184 		dFeedback = 80;
185 		dFeedbackspeed = 10;
186 		dFeedbacksize = 10;
187 		dWireframe = 1;
188 		dTexture = 3;
189 		break;
190 	case PRESET_ECHO:	/* Echo */
191 		dWisps = 3;
192 		dBgWisps = 0;
193 		dDensity = 35;
194 		dVisibility = 30;
195 		dSpeed = 20;
196 		dFeedback = 85;
197 		dFeedbackspeed = 30;
198 		dFeedbacksize = 10;
199 		dWireframe = 0;
200 		dTexture = 1;
201 		break;
202 	case PRESET_KALEIDOSCOPE:	/* Kaleidoscope */
203 		dWisps = 3;
204 		dBgWisps = 0;
205 		dDensity = 35;
206 		dVisibility = 40;
207 		dSpeed = 15;
208 		dFeedback = 90;
209 		dFeedbackspeed = 3;
210 		dFeedbacksize = 10;
211 		dWireframe = 0;
212 		dTexture = 0;
213 		break;
214 	}
215 }
216 
wisp_new(wisp * w)217 void wisp_new (wisp * w)
218 {
219 	int i, j;
220 	float recHalfDens = 1.0f / (dDensity * 0.5f);
221 
222 	w->vertices = (float ***)malloc (sizeof (float **) * (dDensity + 1));
223 	for (i = 0; i <= dDensity; i++) {
224 		w->vertices[i] = (float **)malloc (sizeof (float *) * (dDensity + 1));
225 		for (j = 0; j <= dDensity; j++) {
226 			w->vertices[i][j] = (float *)malloc (sizeof (float) * 7);
227 			w->vertices[i][j][3] = i * recHalfDens - 1.0f;	/* x position on grid */
228 			w->vertices[i][j][4] = j * recHalfDens - 1.0f;	/* y position on grid */
229 
230 			/*
231 			 * distance squared from the center
232 			 */
233 			w->vertices[i][j][5] = w->vertices[i][j][3] * w->vertices[i][j][3] + w->vertices[i][j][4] * w->vertices[i][j][4];
234 
235 			w->vertices[i][j][6] = 0.0f;	/* intensity */
236 		}
237 	}
238 
239 	/*
240 	 * initialize constants
241 	 */
242 	for (i = 0; i < NUMCONSTS; i++) {
243 		w->c[i] = rsRandf (2.0f) - 1.0f;
244 		w->cr[i] = rsRandf (PIx2);
245 		w->cv[i] = rsRandf (dSpeed * 0.03f) + (dSpeed * 0.001f);
246 	}
247 
248 	/*
249 	 * pick color
250 	 */
251 	w->hsl[0] = rsRandf (1.0f);
252 	w->hsl[1] = 0.1f + rsRandf (0.9f);
253 	w->hsl[2] = 1.0f;
254 	w->hueSpeed = rsRandf (0.1f) - 0.05f;
255 	w->saturationSpeed = rsRandf (0.04f) + 0.001f;
256 }
257 
delete_wisp(wisp * w)258 void delete_wisp (wisp * w)
259 {
260 	int i, j;
261 
262 	for (i = 0; i <= dDensity; i++) {
263 		for (j = 0; j <= dDensity; j++) {
264 			free (w->vertices[i][j]);
265 		}
266 		free (w->vertices[i]);
267 	}
268 	free (w->vertices);
269 }
270 
wisp_update(wisp * w)271 void wisp_update (wisp * w)
272 {
273 	int i, j;
274 	rsVec up, right, crossvec;
275 
276 	/*
277 	 * visibility constants
278 	 */
279 	const float viscon1 = dVisibility * 0.01f;
280 	const float viscon2 = 1.0f / viscon1;
281 
282 	/*
283 	 * update constants
284 	 */
285 	for (i = 0; i < NUMCONSTS; i++) {
286 		w->cr[i] += w->cv[i] * elapsedTime;
287 		if (w->cr[i] > PIx2)
288 			w->cr[i] -= PIx2;
289 		w->c[i] = cos (w->cr[i]);
290 	}
291 
292 	/*
293 	 * update vertex positions
294 	 */
295 	for (i = 0; i <= dDensity; i++) {
296 		for (j = 0; j <= dDensity; j++) {
297 			w->vertices[i][j][0] = w->vertices[i][j][3] * w->vertices[i][j][3] * w->vertices[i][j][4] * w->c[0] + w->vertices[i][j][5] * w->c[1] + 0.5f * w->c[2];
298 			w->vertices[i][j][1] = w->vertices[i][j][4] * w->vertices[i][j][4] * w->vertices[i][j][5] * w->c[3] + w->vertices[i][j][3] * w->c[4] + 0.5f * w->c[5];
299 			w->vertices[i][j][2] = w->vertices[i][j][5] * w->vertices[i][j][5] * w->vertices[i][j][3] * w->c[6] + w->vertices[i][j][4] * w->c[7] + w->c[8];
300 		}
301 	}
302 
303 	/*
304 	 * update vertex normals for most of mesh
305 	 */
306 	for (i = 1; i < dDensity; i++) {
307 		for (j = 1; j < dDensity; j++) {
308 			up[0] = w->vertices[i][j + 1][0] - w->vertices[i][j - 1][0];
309 			up[1] = w->vertices[i][j + 1][1] - w->vertices[i][j - 1][1];
310 			up[2] = w->vertices[i][j + 1][2] - w->vertices[i][j - 1][2];
311 
312 			right[0] = w->vertices[i + 1][j][0] - w->vertices[i - 1][j][0];
313 			right[1] = w->vertices[i + 1][j][1] - w->vertices[i - 1][j][1];
314 			right[2] = w->vertices[i + 1][j][2] - w->vertices[i - 1][j][2];
315 
316 			up.normalize();
317 			right.normalize();
318 			crossvec.cross(right, up);
319 
320 			/*
321 			 * Use depth component of normal to compute intensity
322 			 */
323 			/*
324 			 * This way only edges of wisp are bright
325 			 */
326 			if (crossvec[2] < 0.0f)
327 				crossvec[2] *= -1.0f;
328 			w->vertices[i][j][6] = viscon2 * (viscon1 - crossvec[2]);
329 			if (w->vertices[i][j][6] > 1.0f)
330 				w->vertices[i][j][6] = 1.0f;
331 			if (w->vertices[i][j][6] < 0.0f)
332 				w->vertices[i][j][6] = 0.0f;
333 		}
334 	}
335 
336 	/*
337 	 * update color
338 	 */
339 	w->hsl[0] += w->hueSpeed * elapsedTime;
340 	if (w->hsl[0] < 0.0f)
341 		w->hsl[0] += 1.0f;
342 	if (w->hsl[0] > 1.0f)
343 		w->hsl[0] -= 1.0f;
344 	w->hsl[1] += w->saturationSpeed * elapsedTime;
345 	if (w->hsl[1] <= 0.1f) {
346 		w->hsl[1] = 0.1f;
347 		w->saturationSpeed = -w->saturationSpeed;
348 	}
349 	if (w->hsl[1] >= 1.0f) {
350 		w->hsl[1] = 1.0f;
351 		w->saturationSpeed = -w->saturationSpeed;
352 	}
353 	hsl2rgb (w->hsl[0], w->hsl[1], w->hsl[2], w->rgb[0], w->rgb[1], w->rgb[2]);
354 }
355 
wisp_draw(wisp * w)356 void wisp_draw (wisp * w)
357 {
358 	int i, j;
359 
360 	glPushMatrix ();
361 
362 	if (dWireframe) {
363 		for (i = 1; i <= dDensity; i++) {
364 			glBegin (GL_LINE_STRIP);
365 			for (j = 0; j <= dDensity; j++) {
366 				glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
367 				glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
368 				glVertex3fv (w->vertices[i][j]);
369 			}
370 			glEnd ();
371 		}
372 		for (j = 1; j <= dDensity; j++) {
373 			glBegin (GL_LINE_STRIP);
374 			for (i = 0; i <= dDensity; i++) {
375 				glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
376 				glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
377 				glVertex3fv (w->vertices[i][j]);
378 			}
379 			glEnd ();
380 		}
381 	} else {
382 		for (i = 0; i < dDensity; i++) {
383 			glBegin (GL_TRIANGLE_STRIP);
384 			for (j = 0; j <= dDensity; j++) {
385 				glColor3f (w->rgb[0] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[1] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[2] + w->vertices[i + 1][j][6] - 1.0f);
386 				glTexCoord2d (w->vertices[i + 1][j][3] - w->vertices[i + 1][j][0], w->vertices[i + 1][j][4] - w->vertices[i + 1][j][1]);
387 				glVertex3fv (w->vertices[i + 1][j]);
388 				glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
389 				glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
390 				glVertex3fv (w->vertices[i][j]);
391 			}
392 			glEnd ();
393 		}
394 	}
395 
396 	glPopMatrix ();
397 }
398 
wisp_drawAsBackground(wisp * w)399 void wisp_drawAsBackground (wisp * w)
400 {
401 	int i, j;
402 
403 	glPushMatrix ();
404 	glTranslatef (w->c[0] * 0.2f, w->c[1] * 0.2f, 1.6f);
405 
406 	if (dWireframe) {
407 		for (i = 0; i <= dDensity; i++) {
408 			glBegin (GL_LINE_STRIP);
409 			for (j = 0; j <= dDensity; j++) {
410 				glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
411 				glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
412 				glVertex3f (w->vertices[i][j][3], w->vertices[i][j][4], w->vertices[i][j][6]);
413 			}
414 			glEnd ();
415 		}
416 		for (j = 0; j <= dDensity; j++) {
417 			glBegin (GL_LINE_STRIP);
418 			for (i = 0; i <= dDensity; i++) {
419 				glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
420 				glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
421 				glVertex3f (w->vertices[i][j][3], w->vertices[i][j][4], w->vertices[i][j][6]);
422 			}
423 			glEnd ();
424 		}
425 	} else {
426 		for (i = 0; i < dDensity; i++) {
427 			glBegin (GL_TRIANGLE_STRIP);
428 			for (j = 0; j <= dDensity; j++) {
429 				glColor3f (w->rgb[0] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[1] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[2] + w->vertices[i + 1][j][6] - 1.0f);
430 				glTexCoord2d (w->vertices[i + 1][j][3] - w->vertices[i + 1][j][0], w->vertices[i + 1][j][4] - w->vertices[i + 1][j][1]);
431 				glVertex3f (w->vertices[i + 1][j][3], w->vertices[i + 1][j][4], w->vertices[i + 1][j][6]);
432 				glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
433 				glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
434 				glVertex3f (w->vertices[i][j][3], w->vertices[i][j][4], w->vertices[i][j][6]);
435 			}
436 			glEnd ();
437 		}
438 	}
439 
440 	glPopMatrix ();
441 }
442 
hack_draw(xstuff_t * XStuff,double currentTime,float frameTime)443 void hack_draw (xstuff_t * XStuff, double currentTime, float frameTime)
444 {
445 	int i;
446 #ifdef BENCHMARK
447 	static int a = 1;
448 #endif
449 
450 	if (frameTime > 0)
451 		elapsedTime = frameTime;
452 
453 #ifdef BENCHMARK
454 	elapsedTime = 0.001;
455 #endif
456 
457 	/*
458 	 * Update wisps
459 	 */
460 	for (i = 0; i < dWisps; i++)
461 		wisp_update (&wisps[i]);
462 	for (i = 0; i < dBgWisps; i++)
463 		wisp_update (&backwisps[i]);
464 
465 	if (dFeedback) {
466 		float feedbackIntensity = dFeedback / 101.0f;
467 
468 		/*
469 		 * update feedback variables
470 		 */
471 		for (i = 0; i < 4; i++) {
472 			fr[i] += elapsedTime * fv[i];
473 			if (fr[i] > PIx2)
474 				fr[i] -= PIx2;
475 		}
476 		f[0] = 30.0f * cos (fr[0]);
477 		f[1] = 0.2f * cos (fr[1]);
478 		f[2] = 0.2f * cos (fr[2]);
479 		f[3] = 0.8f * cos (fr[3]);
480 		for (i = 0; i < 3; i++) {
481 			lr[i] += elapsedTime * lv[i];
482 			if (lr[i] > PIx2)
483 				lr[i] -= PIx2;
484 			l[i] = cos (lr[i]);
485 			l[i] = l[i] * l[i];
486 		}
487 
488 		/*
489 		 * Create drawing area for feedback texture
490 		 */
491 		glViewport (0, 0, feedbacktexsize, feedbacktexsize);
492 		glMatrixMode (GL_PROJECTION);
493 		glLoadIdentity ();
494 		gluPerspective (30.0, aspectRatio, 0.01f, 20.0f);
495 		glMatrixMode (GL_MODELVIEW);
496 
497 		/*
498 		 * Draw
499 		 */
500 		glClear (GL_COLOR_BUFFER_BIT);
501 		glColor3f (feedbackIntensity, feedbackIntensity, feedbackIntensity);
502 		glBindTexture (GL_TEXTURE_2D, feedbacktex);
503 		glPushMatrix ();
504 		glTranslatef (f[1] * l[1], f[2] * l[1], f[3] * l[2]);
505 		glRotatef (f[0] * l[0], 0, 0, 1);
506 		glBegin (GL_TRIANGLE_STRIP);
507 		glTexCoord2f (-0.5f, -0.5f);
508 		glVertex3f (-aspectRatio * 2.0f, -2.0f, 1.25f);
509 		glTexCoord2f (1.5f, -0.5f);
510 		glVertex3f (aspectRatio * 2.0f, -2.0f, 1.25f);
511 		glTexCoord2f (-0.5f, 1.5f);
512 		glVertex3f (-aspectRatio * 2.0f, 2.0f, 1.25f);
513 		glTexCoord2f (1.5f, 1.5f);
514 		glVertex3f (aspectRatio * 2.0f, 2.0f, 1.25f);
515 		glEnd ();
516 		glPopMatrix ();
517 		glBindTexture (GL_TEXTURE_2D, tex);
518 		for (i = 0; i < dBgWisps; i++)
519 			wisp_drawAsBackground (&backwisps[i]);
520 		for (i = 0; i < dWisps; i++)
521 			wisp_draw (&wisps[i]);
522 
523 		/*
524 		 * readback feedback texture
525 		 */
526 		glReadBuffer (GL_BACK);
527 		glPixelStorei (GL_UNPACK_ROW_LENGTH, feedbacktexsize);
528 		glBindTexture (GL_TEXTURE_2D, feedbacktex);
529 		glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 0, 0, feedbacktexsize, feedbacktexsize);
530 
531 		/*
532 		 * create regular drawing area
533 		 */
534 		glViewport (0, 0, XStuff->windowWidth, XStuff->windowHeight);
535 		glMatrixMode (GL_PROJECTION);
536 		glLoadIdentity ();
537 		gluPerspective (20.0, aspectRatio, 0.01f, 20.0f);
538 		glMatrixMode (GL_MODELVIEW);
539 
540 		/*
541 		 * Draw again
542 		 */
543 		glClear (GL_COLOR_BUFFER_BIT);
544 		glColor3f (feedbackIntensity, feedbackIntensity, feedbackIntensity);
545 		glPushMatrix ();
546 		glTranslatef (f[1] * l[1], f[2] * l[1], f[3] * l[2]);
547 		glRotatef (f[0] * l[0], 0, 0, 1);
548 		glBegin (GL_TRIANGLE_STRIP);
549 		glTexCoord2f (-0.5f, -0.5f);
550 		glVertex3f (-aspectRatio * 2.0f, -2.0f, 1.25f);
551 		glTexCoord2f (1.5f, -0.5f);
552 		glVertex3f (aspectRatio * 2.0f, -2.0f, 1.25f);
553 		glTexCoord2f (-0.5f, 1.5f);
554 		glVertex3f (-aspectRatio * 2.0f, 2.0f, 1.25f);
555 		glTexCoord2f (1.5f, 1.5f);
556 		glVertex3f (aspectRatio * 2.0f, 2.0f, 1.25f);
557 		glEnd ();
558 		glPopMatrix ();
559 
560 		glBindTexture (GL_TEXTURE_2D, tex);
561 	} else
562 		glClear (GL_COLOR_BUFFER_BIT);
563 
564 	for (i = 0; i < dBgWisps; i++)
565 		wisp_drawAsBackground (&backwisps[i]);
566 	for (i = 0; i < dWisps; i++)
567 		wisp_draw (&wisps[i]);
568 
569 	glFlush ();
570 
571 #ifdef BENCHMARK
572 	if (a++ == 10000)
573 		exit(0);
574 #endif
575 }
576 
hack_reshape(xstuff_t * XStuff)577 void hack_reshape (xstuff_t * XStuff)
578 {
579 	aspectRatio = (GLfloat) XStuff->windowWidth / (GLfloat) XStuff->windowHeight;
580 
581 	glViewport (0, 0, (GLint) XStuff->windowWidth, (GLint) XStuff->windowHeight);
582 
583 	/*
584 	 * setup regular drawing area just in case feedback isnt used
585 	 */
586 	glMatrixMode (GL_PROJECTION);
587 	glLoadIdentity ();
588 	gluPerspective (20.0, aspectRatio, 0.01, 20);
589 	glMatrixMode (GL_MODELVIEW);
590 	glLoadIdentity ();
591 	glTranslatef (0.0, 0.0, -5.0);
592 
593 	glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
594 	glClear (GL_COLOR_BUFFER_BIT);
595 	glEnable (GL_BLEND);
596 	glBlendFunc (GL_ONE, GL_ONE);
597 	glLineWidth (2.0f);
598 
599 	/*
600 	 * Commented out because smooth lines and textures dont mix on my TNT.
601 	 * Its like it rendering in software mode
602 	 */
603 
604 	/*
605 	 * glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
606 	 */
607 }
608 
hack_init(xstuff_t * XStuff)609 void hack_init (xstuff_t * XStuff)
610 {
611 	int i;
612 
613 	hack_reshape (XStuff);
614 
615 	if (dTexture) {
616 		int whichtex = dTexture;
617 		unsigned char *l_tex = NULL;
618 
619 		if (whichtex == 4)	/* random texture */
620 			whichtex = rsRandi (3) + 1;
621 		glEnable (GL_TEXTURE_2D);
622 		glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
623 		/*
624 		 * Initialize texture
625 		 */
626 		glGenTextures (1, &tex);
627 		glBindTexture (GL_TEXTURE_2D, tex);
628 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
629 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
630 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
631 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
632 		switch (whichtex) {
633 		case 1:
634 			LOAD_TEXTURE (l_tex, plasmamap, plasmamap_compressedsize, plasmamap_size)
635 				break;
636 		case 2:
637 			LOAD_TEXTURE (l_tex, stringymap, stringymap_compressedsize, stringymap_size)
638 				break;
639 		case 3:
640 			LOAD_TEXTURE (l_tex, linesmap, linesmap_compressedsize, linesmap_size)
641 		}
642 
643 		gluBuild2DMipmaps (GL_TEXTURE_2D, 1, TEXSIZE, TEXSIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, l_tex);
644 		FREE_TEXTURE (l_tex)
645 	}
646 
647 	if (dFeedback) {
648 		feedbacktexsize = 1 << dFeedbacksize;
649 		while (feedbacktexsize > XStuff->windowWidth || feedbacktexsize > XStuff->windowHeight) {
650 			dFeedbacksize -= 1;
651 			feedbacktexsize = 1 << dFeedbacksize;
652 		}
653 
654 		/*
655 		 * feedback texture setup
656 		 */
657 		glEnable (GL_TEXTURE_2D);
658 		glGenTextures (1, &feedbacktex);
659 		glBindTexture (GL_TEXTURE_2D, feedbacktex);
660 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
661 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
662 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
663 		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
664 		glTexImage2D (GL_TEXTURE_2D, 0, 3, feedbacktexsize, feedbacktexsize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
665 
666 		/*
667 		 * feedback velocity variable setup
668 		 */
669 		fv[0] = (float)dFeedbackspeed * (rsRandf (0.025f) + 0.025f);
670 		fv[1] = (float)dFeedbackspeed * (rsRandf (0.05f) + 0.05f);
671 		fv[2] = (float)dFeedbackspeed * (rsRandf (0.05f) + 0.05f);
672 		fv[3] = (float)dFeedbackspeed * (rsRandf (0.1f) + 0.1f);
673 		lv[0] = (float)dFeedbackspeed * (rsRandf (0.0025f) + 0.0025f);
674 		lv[1] = (float)dFeedbackspeed * (rsRandf (0.0025f) + 0.0025f);
675 		lv[2] = (float)dFeedbackspeed * (rsRandf (0.0025f) + 0.0025f);
676 	}
677 
678 	/*
679 	 * Initialize wisps
680 	 */
681 	if (dWisps > 0) {
682 		wisps = (wisp *) malloc (sizeof (wisp) * dWisps);
683 		for (i = 0; i < dWisps; i++) {
684 			wisp_new (&wisps[i]);
685 		}
686 	}
687 
688 	if (dBgWisps > 0) {
689 		backwisps = (wisp *) malloc (sizeof (wisp) * dBgWisps);
690 		for (i = 0; i < dBgWisps; i++) {
691 			wisp_new (&backwisps[i]);
692 		}
693 	}
694 }
695 
hack_cleanup(xstuff_t * XStuff)696 void hack_cleanup (xstuff_t * XStuff)
697 {
698 }
699 
hack_handle_opts(int argc,char ** argv)700 void hack_handle_opts (int argc, char **argv)
701 {
702 	int change_flag = 0;
703 
704 	setDefaults (PRESET_REGULAR);
705 
706 	while (1) {
707 		int c;
708 
709 #ifdef HAVE_GETOPT_H
710 		static struct option long_options[] = {
711 			{"help", 0, 0, 'h'},
712 			DRIVER_OPTIONS_LONG
713 			{"preset", 1, 0, 'p'},
714 			{"regular", 0, 0, 10},
715 			{"grid", 0, 0, 11},
716 			{"cubism", 0, 0, 12},
717 			{"badmath", 0, 0, 13},
718 			{"mtheory", 0, 0, 14},
719 			{"uhftem", 0, 0, 15},
720 			{"nowhere", 0, 0, 16},
721 			{"echo", 0, 0, 17},
722 			{"kaleidoscope", 0, 0, 18},
723 			{"wisps", 1, 0, 'i'},
724 			{"bgwisps", 1, 0, 'b'},
725 			{"density", 1, 0, 'd'},
726 			{"visibility", 1, 0, 'v'},
727 			{"speed", 1, 0, 's'},
728 			{"feedback", 1, 0, 'f'},
729 			{"feedbackspeed", 1, 0, 'e'},
730 			{"feedbacksize", 1, 0, 'c'},
731 			{"wireframe", 0, 0, 'w'},
732 			{"no-wireframe", 0, 0, 'W'},
733 			{"texture", 1, 0, 't'},
734 			{"plasma", 0, 0, 1},
735 			{"stringy", 0, 0, 2},
736 			{"linear", 0, 0, 3},
737 			{0, 0, 0, 0}
738 		};
739 
740 		c = getopt_long (argc, argv, DRIVER_OPTIONS_SHORT "hp:i:b:d:v:s:f:e:c:wWt:", long_options, NULL);
741 #else
742 		c = getopt (argc, argv, DRIVER_OPTIONS_SHORT "hp:i:b:d:v:s:f:e:c:wWt:");
743 #endif
744 		if (c == -1)
745 			break;
746 
747 		switch (c) {
748 		DRIVER_OPTIONS_CASES
749 		case 'h':
750 			printf ("%s:"
751 #ifndef HAVE_GETOPT_H
752 				" Not built with GNU getopt.h, long options *NOT* enabled."
753 #endif
754 				"\n" DRIVER_OPTIONS_HELP
755 				"\t--preset/-p <arg>\n" "\t--regular\n" "\t--grid\n" "\t--cubism\n" "\t--badmath\n" "\t--mtheory\n" "\t--uhftem\n" "\t--nowhere\n" "\t--echo\n" "\t--kaleidoscope\n"
756 				"\t--wisps/-i <arg>\n" "\t--bgwisps/-b <arg>\n"
757 				"\t--density/-d <arg>\n" "\t--visibility/-v <arg>\n" "\t--speed/-s <arg>\n"
758 				"\t--feedback/-f <arg>\n" "\t--feedbackspeed/-e <arg>\n" "\t--feedbacksize/-c <arg>\n"
759 				"\t--wireframe/-w\n" "\t--no-wireframe/-W\n"
760 				"\t--texture/-t <arg>\n" "\t--plasma\n" "\t--stringy\n" "\t--linear\n", argv[0]);
761 			exit (1);
762 		case 'p':
763 			change_flag = 1;
764 			setDefaults (strtol_minmaxdef (optarg, 10, 1, 9, 0, 1, "--preset: "));
765 			break;
766 		case 10:
767 		case 11:
768 		case 12:
769 		case 13:
770 		case 14:
771 		case 15:
772 		case 16:
773 		case 17:
774 		case 18:
775 			change_flag = 1;
776 			setDefaults (c - 9);
777 			break;
778 		case 'i':
779 			change_flag = 1;
780 			dWisps = strtol_minmaxdef (optarg, 10, 0, 128, 1, 1, "--wisps: ");
781 			break;
782 		case 'b':
783 			change_flag = 1;
784 			dBgWisps = strtol_minmaxdef (optarg, 10, 0, 128, 1, 1, "--bgwisps: ");
785 			break;
786 		case 'd':
787 			change_flag = 1;
788 			dDensity = strtol_minmaxdef (optarg, 10, 2, 1000, 1, 1, "--density: ");
789 			break;
790 		case 'v':
791 			change_flag = 1;
792 			dVisibility = strtol_minmaxdef (optarg, 10, 1, 100, 1, 1, "--visibility: ");
793 			break;
794 		case 's':
795 			change_flag = 1;
796 			dSpeed = strtol_minmaxdef (optarg, 10, 1, 100, 1, 1, "--speed: ");
797 			break;
798 		case 'f':
799 			change_flag = 1;
800 			dFeedback = strtol_minmaxdef (optarg, 10, 0, 100, 1, 1, "--feedback: ");
801 			break;
802 		case 'e':
803 			change_flag = 1;
804 			dFeedbackspeed = strtol_minmaxdef (optarg, 10, 1, 10, 1, 1, "--feedbackspeed: ");
805 			break;
806 		case 'c':
807 			change_flag = 1;
808 			dFeedbacksize = 1 << strtol_minmaxdef (optarg, 10, 1, 10, 1, 1, "--feedbacksize: ");
809 			break;
810 		case 'w':
811 			change_flag = 1;
812 			dWireframe = 1;
813 			break;
814 		case 'W':
815 			change_flag = 1;
816 			dWireframe = 0;
817 			break;
818 		case 't':
819 			change_flag = 1;
820 			dTexture = strtol_minmaxdef (optarg, 10, 0, 4, 0, 1, "--texture: ");
821 			break;
822 		case 1:
823 		case 2:
824 		case 3:
825 			change_flag = 1;
826 			dTexture = c;
827 			break;
828 		}
829 	}
830 
831 	if (!change_flag) {
832 		setDefaults (rsRandi (9) + 1);
833 	}
834 }
835