1 /*
2  * Permission to use, copy, modify, and distribute this software and its
3  * documentation for any purpose and without fee is hereby granted,
4  * provided that the above copyright notice appear in all copies and that
5  * both that copyright notice and this permission notice appear in
6  * supporting documentation.
7  *
8  * This file is provided AS IS with no warranties of any kind.  The author
9  * shall have no liability with respect to the infringement of copyrights,
10  * trade secrets or any patents by this file or any part thereof.  In no
11  * event will the author be liable for any lost revenue or profits or
12  * other special, indirect and consequential damages.
13  *
14  * Copyright 2004 Blair Tennessy
15  * tennessy@cs.ubc.ca
16  */
17 
18 #if 0
19 static const char sccsid[] = "@(#)antmaze.c	5.01 2001/03/01 xlockmore";
20 #endif
21 
22 #ifdef STANDALONE
23 # define MODE_antmaze
24 # define DEFAULTS	"*delay:		20000   \n"	\
25 			"*showFPS:      False   \n" \
26 			"*fpsSolid:     True    \n"
27 
28 # define release_antmaze 0
29 # include "xlockmore.h"		/* from the xscreensaver distribution */
30 #else /* !STANDALONE */
31 # include "xlock.h"		/* from the xlockmore distribution */
32 #endif /* !STANDALONE */
33 
34 #ifdef HAVE_JWXYZ
35 # include "jwxyz.h"
36 #else
37 # include <X11/Xlib.h>
38 # include <GL/gl.h>
39 # include <GL/glu.h>
40 #endif
41 
42 #ifdef HAVE_JWZGLES
43 # include "jwzgles.h"
44 #endif /* HAVE_JWZGLES */
45 
46 #ifdef MODE_antmaze
47 
48 
49 #include "sphere.h"
50 #include "tube.h"
51 #include "rotator.h"
52 #include "gltrackball.h"
53 
54 #define DEF_SOLIDANTMAZE  "False"
55 #define DEF_NOANTS  "False"
56 
57 static int  solidantmaze;
58 static int  noants;
59 
60 static XrmOptionDescRec opts[] =
61 {
62   {"-solidantmaze", ".antmaze.solidantmaze", XrmoptionNoArg, "on"},
63   {"+solidantmaze", ".antmaze.solidantmaze", XrmoptionNoArg, "off"},
64   {"-noants", ".antmaze.noants", XrmoptionNoArg, "on"},
65   {"+noants", ".antmaze.noants", XrmoptionNoArg, "off"}
66 };
67 static argtype vars[] =
68 {
69   {&solidantmaze, "solidantmaze", "Solidantmaze", DEF_SOLIDANTMAZE, t_Bool},
70   {&noants, "noants", "Noants", DEF_NOANTS, t_Bool}
71 };
72 
73 static OptionStruct desc[] =
74 {
75 	{"-/+solidantmaze", "select between a SOLID or a NET Antmaze Strip"},
76 	{"-/+noants", "turn on/off walking ants"}
77 };
78 
79 ENTRYPOINT ModeSpecOpt antmaze_opts =
80 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
81 
82 #ifdef USE_MODULES
83 ModStruct   antmaze_description =
84 {"antmaze", "init_antmaze", "draw_antmaze", NULL,
85  "draw_antmaze", "change_antmaze", NULL, &antmaze_opts,
86  1000, 1, 1, 1, 4, 1.0, "",
87  "draws some ants", 0, NULL};
88 
89 #endif
90 
91 #define Scale4Window               0.3
92 #define Scale4Iconic               0.4
93 
94 #define sqr(A)                     ((A)*(A))
95 
96 #ifndef Pi
97 #define Pi                         M_PI
98 #endif
99 
100 #define ObjAntmazeStrip 0
101 #define ObjAntBody      1
102 #define MaxObj          2
103 
104 /*************************************************************************/
105 
106 #include "ants.h"
107 
108 #define ANTCOUNT 5
109 #define PI 3.14157
110 
111 #define EPSILON 0.01
112 #define BOARDSIZE 10
113 #define BOARDCOUNT 2
114 #define PARTS 20
115 
116 #define checkImageWidth 64
117 #define checkImageHeight 64
118 
119 typedef struct {
120   GLint       WindH, WindW;
121   GLfloat     step;
122   GLfloat     ant_position;
123   GLXContext *glx_context;
124   rotator    *rot;
125   trackball_state *trackball;
126   Bool        button_down_p;
127 
128   int focus;
129   int currentboard;
130 
131   double antdirection[ANTCOUNT];
132   double antposition[ANTCOUNT][3];
133   int anton[ANTCOUNT];
134 
135   double antvelocity[ANTCOUNT];
136   double antsize[ANTCOUNT];
137   int bposition[ANTCOUNT][2];
138   int board[BOARDCOUNT][10][10];
139 
140   int part[ANTCOUNT];
141   double antpath[ANTCOUNT][PARTS][2];
142   int antpathlength[ANTCOUNT];
143 
144   GLubyte checkers[checkImageWidth][checkImageHeight][3];
145 
146   GLuint checktexture, brushedtexture;
147   double elevator;
148 
149   double ant_step;
150   double first_ant_step;
151   int started;
152   int introduced;
153   int entroducing;
154 
155   double fadeout;
156   double fadeoutspeed;
157 
158   int mag;
159 
160 } antmazestruct;
161 
162 static antmazestruct *antmaze = (antmazestruct *) NULL;
163 
164 
165 static const GLfloat MaterialRed[] = {0.6, 0.0, 0.0, 1.0};
166 /*static const GLfloat MaterialMagenta[] = {0.6, 0.2, 0.5, 1.0};*/
167 static const GLfloat MaterialGray8[] = {0.8, 0.8, 0.8, 1.0};
168 static const GLfloat MaterialGray35[] = {0.30, 0.30, 0.30, 1.0};
169 static const GLfloat MaterialGray4[] = {0.40, 0.40, 0.40, 1.0};
170 static const GLfloat MaterialOrange[] = {1.0, 0.69, 0.00, 1.0};
171 static const GLfloat MaterialGreen[] = {0.1, 0.4, 0.2, 1.0};
172 
173 /* lighting variables */
174 static const GLfloat front_shininess[] = {60.0};
175 static const GLfloat front_specular[] = {0.8, 0.8, 0.8, 1.0};
176 static const GLfloat ambient[] = {0.1, 0.1, 0.1, 1.0};
177 /*static const GLfloat ambient2[] = {0.0, 0.0, 0.0, 0.0};*/
178 static const GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0};
179 static const GLfloat position0[] = {1.0, 5.0, 1.0, 1.0};
180 static const GLfloat position1[] = {-1.0, -5.0, 1.0, 1.0};
181 /*static const GLfloat lmodel_ambient[] = {0.8, 0.8, 0.8, 1.0};*/
182 /*static const GLfloat lmodel_twoside[] = {GL_TRUE};*/
183 /*static const GLfloat spotlight_ambient[] = { 0.0, 0.0, 0.0, 1.0 };*/
184 /*static const GLfloat spotlight_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };*/
185 
186 #define NUM_SCENES      2
187 
188 /* filled sphere */
mySphere(float radius)189 static Bool mySphere(float radius)
190 {
191 #if 0
192   GLUquadricObj *quadObj;
193 
194   if((quadObj = gluNewQuadric()) == 0)
195 	return False;
196   gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
197   gluSphere(quadObj, radius, 16, 16);
198   gluDeleteQuadric(quadObj);
199 #else
200     glPushMatrix();
201     glScalef (radius, radius, radius);
202     glRotatef (90, 1, 0, 0);
203     unit_sphere (16, 16, False);
204     glPopMatrix();
205 #endif
206   return True;
207 }
208 
209 #if 0
210 /* silhouette sphere */
211 static Bool mySphere2(float radius)
212 {
213   GLUquadricObj *quadObj;
214 
215   if((quadObj = gluNewQuadric()) == 0)
216 	return False;
217   gluQuadricDrawStyle(quadObj, (GLenum) GLU_SILHOUETTE);
218   gluSphere(quadObj, radius, 16, 8);
219   gluDeleteQuadric(quadObj);
220 
221   return True;
222 }
223 #endif
224 
225 /* textured sphere */
mySphereTex(float radius)226 static Bool mySphereTex(float radius)
227 {
228 #if 0
229   GLUquadricObj *quadObj;
230 
231   if((quadObj = gluNewQuadric()) == 0)
232 	return False;
233   gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
234   gluQuadricTexture(quadObj, GL_TRUE);
235   gluQuadricNormals(quadObj, GLU_SMOOTH);
236   gluSphere(quadObj, radius, 32, 16);
237   gluDeleteQuadric(quadObj);
238 #else
239     glPushMatrix();
240     glScalef (radius, radius, radius);
241     glRotatef (90, 1, 0, 0);
242     unit_sphere (32, 16, False);
243     glPopMatrix();
244 #endif
245 
246   return True;
247 }
248 
249 /* filled cone */
myCone(float radius)250 static Bool myCone(float radius)
251 {
252 #if 0
253   GLUquadricObj *quadObj;
254 
255   if ((quadObj = gluNewQuadric()) == 0)
256     return False;
257   gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
258   gluCylinder(quadObj, radius, 0, radius * 2, 8, 1);
259   gluDeleteQuadric(quadObj);
260 #else
261     cone (0, 0, 0,
262           0, 0, radius * 2,
263           radius, 0,
264           8, True, True, False);
265 #endif
266   return True;
267 }
268 
269 /* no cone */
myCone2(float radius)270 static Bool myCone2(float radius) { return True; }
271 
272 #define MATERIALS 4
273 static const float *antmaterial[ANTCOUNT] =
274   {MaterialRed, MaterialGray35, MaterialGray4, MaterialOrange, MaterialGreen};
275 
276 static const float *materials[MATERIALS] =
277   {MaterialRed, MaterialGray35, MaterialGray4, MaterialOrange};
278 
279 
makeCheckImage(antmazestruct * mp)280 static void makeCheckImage(antmazestruct *mp)
281 {
282   int i, j;
283 
284   for (i = 0; i < checkImageWidth; i++) {
285     for (j = 0; j < checkImageHeight; j++) {
286       if(((((i&0x8)==0)^((j&0x8)))==0)) {
287 	int c = 102 + random()%32;
288 	mp->checkers[i][j][0] = c;
289 	mp->checkers[i][j][1] = c;
290 	mp->checkers[i][j][2] = c;
291       }
292       else {
293 	int c = 153 + random()%32;
294 	mp->checkers[i][j][0] = c;/*153;*/
295 	mp->checkers[i][j][1] = c;/*c;*//*0;*/
296 	mp->checkers[i][j][2] = c;/*c;*//*0;*/
297       }
298     }
299   }
300 
301   glGenTextures(1, &mp->checktexture);
302   glBindTexture(GL_TEXTURE_2D, mp->checktexture);
303 
304   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
305   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
306   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
307   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
308   glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
309 	       checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
310 	       &mp->checkers[0][0]);
311   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
312 }
313 
makeBrushedImage(antmazestruct * mp)314 static void makeBrushedImage(antmazestruct *mp)
315 {
316   int i, j, c;
317 
318   for(i = 0; i < checkImageWidth; ++i)
319     for(j = 0; j < checkImageHeight; ++j) {
320 
321       c = 102+102*fabs(sin(2.0*i / Pi)*sin(2.0*j/Pi)) + random()%51;
322 
323 /*       c = (i+j)%8==0 || (i+j+5)%8==0 ? 153 : 102; */
324 
325       mp->checkers[i][j][0] = c;
326       mp->checkers[i][j][1] = c;
327       mp->checkers[i][j][2] = c;
328     }
329 
330 /*   for (i = 0; i < checkImageWidth; i++) { */
331 /*     for (j = 0; j < checkImageHeight; j++) { */
332 /*       int c = 102 + pow((random()%1000)/1000.0, 4)*103; */
333 /*       checkers[i][j][0] = c; */
334 /*       checkers[i][j][1] = c; */
335 /*       checkers[i][j][2] = c; */
336 /*     } */
337 /*   } */
338 
339 /*   /\* smooth *\/ */
340 /*   for (i = 0; i < checkImageWidth; i++) { */
341 /*     for (j = 0; j < checkImageHeight; j++) { */
342 /*       int a = checkers[(i+checkImageWidth+1)%checkImageWidth][j][0] +  */
343 /* 	4*checkers[i][j][0] + checkers[(i+1)%checkImageWidth][j][0]; */
344 /*       a /= 6; */
345 /*       checkers[i][j][0] = a; */
346 /*       checkers[i][j][1] = a; */
347 /*       checkers[i][j][2] = a; */
348 /*     } */
349 /*   } */
350 
351   glGenTextures(1, &mp->brushedtexture);
352   glBindTexture(GL_TEXTURE_2D, mp->brushedtexture);
353 
354   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
355   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
356   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
357   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
358   glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
359 	       checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
360 	       &mp->checkers[0][0]);
361   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
362 }
363 
364 #if 0
365 static void draw_wall(ModeInfo *mi, double x1, double z1, double x2, double z2)
366 {
367   float x = fabs(x2 - x1)/2.0;
368 
369   glBegin(GL_QUADS);
370 
371   /* draw top */
372   glNormal3f(0.0, 1.0, 0.0);
373   glTexCoord2f(0.0, 0.0);
374   glVertex3f(x1, 1.0, z1+0.25);
375   glTexCoord2f(x, 0.0);
376   glVertex3f(x2, 1.0, z2+0.25);
377   glTexCoord2f(x, 0.25);
378   glVertex3f(x2, 1.0, z2-0.25);
379   glTexCoord2f(0.0, 0.25);
380   glVertex3f(x1, 1.0, z1-0.25);
381   mi->polygon_count++;
382 
383   /* draw sides */
384   glNormal3f(0.0, 0.0, 1.0);
385   glTexCoord2f(0.0, 0.0);
386   glVertex3f(x1, 0.0, z1+0.25);
387   glTexCoord2f(x, 0.0);
388   glVertex3f(x2, 0.0, z2+0.25);
389   glTexCoord2f(x, 0.5);
390   glVertex3f(x2, 1.0, z2+0.25);
391   glTexCoord2f(0.0, 0.5);
392   glVertex3f(x1, 1.0, z1+0.25);
393   mi->polygon_count++;
394 
395   glNormal3f(0.0, 0.0, -1.0);
396   glTexCoord2f(0.0, 0.0);
397   glVertex3f(x1, 0.0, z1-0.25);
398   glTexCoord2f(x, 0.0);
399   glVertex3f(x2, 0.0, z2-0.25);
400   glTexCoord2f(x, 0.5);
401   glVertex3f(x2, 1.0, z2-0.25);
402   glTexCoord2f(0.0, 0.5);
403   glVertex3f(x1, 1.0, z1-0.25);
404   mi->polygon_count++;
405 
406   /* draw ends */
407   glNormal3f(1.0, 0.0, 0.0);
408   glTexCoord2f(0.0, 0.0);
409   glVertex3f(x2, 0.0, z2+0.25);
410   glTexCoord2f(0.25, 0.0);
411   glVertex3f(x2, 0.0, z2-0.25);
412   glTexCoord2f(0.25, 0.5);
413   glVertex3f(x2, 1.0, z2-0.25);
414   glTexCoord2f(0.0, 0.5);
415   glVertex3f(x2, 1.0, z2+0.25);
416   mi->polygon_count++;
417 
418   glNormal3f(-1.0, 0.0, 0.0);
419   glTexCoord2f(0.0, 0.0);
420   glVertex3f(x1, 0.0, z1-0.25);
421   glTexCoord2f(0.25, 0.0);
422   glVertex3f(x1, 0.0, z1+0.25);
423   glTexCoord2f(0.25, 0.5);
424   glVertex3f(x1, 1.0, z1+0.25);
425   glTexCoord2f(0.0, 0.5);
426   glVertex3f(x1, 1.0, z1-0.25);
427   mi->polygon_count++;
428 
429   glEnd();
430 }
431 #endif
432 
draw_board(ModeInfo * mi,antmazestruct * mp)433 static void draw_board(ModeInfo *mi, antmazestruct *mp)
434 {
435 
436   int i, j;
437   double h = 0.5;
438   double stf = 0.0625;
439 
440   glBindTexture(GL_TEXTURE_2D, mp->checktexture);
441 
442   glBegin(GL_QUADS);
443 
444   for(i = 0; i < BOARDSIZE; ++i)
445     for(j = 0; j < BOARDSIZE; ++j) {
446       if(mp->board[mp->currentboard][j][i]) {
447 
448 /* 	/\* draw top *\/ */
449 /* 	glNormal3f(0.0, 1.0, 0.0); */
450 /* 	glTexCoord2f(0.0 + stf, 0.0 + stf); */
451 /* 	glVertex3f(i-0.5, h, j+0.5); */
452 /* 	glTexCoord2f(1.0 + stf, 0.0 + stf); */
453 /* 	glVertex3f(i+0.5, h, j+0.5); */
454 /* 	glTexCoord2f(1.0 + stf, 1.0 + stf); */
455 /* 	glVertex3f(i+0.5, h, j-0.5); */
456 /* 	glTexCoord2f(0.0 + stf, 1.0 + stf); */
457 /* 	glVertex3f(i-0.5, h, j-0.5); */
458 
459 	/* draw top */
460 	glNormal3f(0.0, 1.0, 0.0);
461 	glTexCoord2f(0.0 + stf, 0.0 + stf);
462 	glVertex3f(i-0.5, h, j+0.5);
463 	glTexCoord2f(1.0 + stf, 0.0 + stf);
464 	glVertex3f(i+0.5, h, j+0.5);
465 	glTexCoord2f(1.0 + stf, 1.0 + stf);
466 	glVertex3f(i+0.5, h, j-0.5);
467 	glTexCoord2f(0.0 + stf, 1.0 + stf);
468 	glVertex3f(i-0.5, h, j-0.5);
469         mi->polygon_count++;
470 
471 	/* draw south face */
472 	if(j == 9 || !mp->board[mp->currentboard][j+1][i]) {
473 	  glNormal3f(0.0, 0.0, 1.0);
474 	  glTexCoord2f(0.0 + stf, 0.0 + stf);
475 	  glVertex3f(i-0.5, 0.0, j+0.5);
476 	  glTexCoord2f(1.0 + stf, 0.0 + stf);
477 	  glVertex3f(i+0.5, 0.0, j+0.5);
478 	  glTexCoord2f(1.0 + stf, h + stf);
479 	  glVertex3f(i+0.5, h, j+0.5);
480 	  glTexCoord2f(0.0 + stf, h + stf);
481 	  glVertex3f(i-0.5, h, j+0.5);
482           mi->polygon_count++;
483 	}
484 
485 	/* draw north face */
486 	if(j == 0 || !mp->board[mp->currentboard][j-1][i]) {
487 	  glNormal3f(0.0, 0.0, -1.0);
488 	  glTexCoord2f(0.0 + stf, 0.0 + stf);
489 	  glVertex3f(i+0.5, 0.0, j-0.5);
490 	  glTexCoord2f(1.0 + stf, 0.0 + stf);
491 	  glVertex3f(i-0.5, 0.0, j-0.5);
492 	  glTexCoord2f(1.0 + stf, h + stf);
493 	  glVertex3f(i-0.5, h, j-0.5);
494 	  glTexCoord2f(0.0 + stf, h + stf);
495 	  glVertex3f(i+0.5, h, j-0.5);
496           mi->polygon_count++;
497 	}
498 
499 	/* draw east face */
500 	if(i == 9 || !mp->board[mp->currentboard][j][i+1]) {
501 	  glNormal3f(1.0, 0.0, 0.0);
502 	  glTexCoord2f(0.0 + stf, 0.0 + stf);
503 	  glVertex3f(i+0.5, 0.0, j+0.5);
504 	  glTexCoord2f(1.0 + stf, 0.0 + stf);
505 	  glVertex3f(i+0.5, 0.0, j-0.5);
506 	  glTexCoord2f(1.0 + stf, h + stf);
507 	  glVertex3f(i+0.5, h, j-0.5);
508 	  glTexCoord2f(0.0 + stf, h + stf);
509 	  glVertex3f(i+0.5, h, j+0.5);
510           mi->polygon_count++;
511 	}
512 
513 	/* draw west face */
514 	if(i == 0 || !mp->board[mp->currentboard][j][i-1]) {
515 	  glNormal3f(-1.0, 0.0, 0.0);
516 	  glTexCoord2f(0.0 + stf, 0.0 + stf);
517 	  glVertex3f(i-0.5, 0.0, j-0.5);
518 	  glTexCoord2f(1.0 + stf, 0.0 + stf);
519 	  glVertex3f(i-0.5, 0.0, j+0.5);
520 	  glTexCoord2f(1.0 + stf, h + stf);
521 	  glVertex3f(i-0.5, h, j+0.5);
522 	  glTexCoord2f(0.0 + stf, h + stf);
523 	  glVertex3f(i-0.5, h, j-0.5);
524           mi->polygon_count++;
525 	}
526       }
527       else {
528 	double tx = 2.0;
529 	glNormal3f(0.0, 1.0, 0.0);
530 	glTexCoord2f(0.0, 0.0);
531 	glVertex3f(i-0.5, 0.0, j+0.5);
532 	glTexCoord2f(tx, 0.0);
533 	glVertex3f(i+0.5, 0.0, j+0.5);
534 	glTexCoord2f(tx, tx);
535 	glVertex3f(i+0.5, 0.0, j-0.5);
536 	glTexCoord2f(0.0, tx);
537 	glVertex3f(i-0.5, 0.0, j-0.5);
538         mi->polygon_count++;
539       }
540     }
541   glEnd();
542 
543 /*   /\* draw elevator *\/ */
544 /*   glBindTexture(GL_TEXTURE_2D, brushedtexture); */
545 
546 /*   glBegin(GL_QUADS); */
547 
548 /*   glNormal3f(0.0, 1.0, 0.0); */
549 
550 /*   if(pastfirst) { */
551 /*       /\* source *\/ */
552 /*       glTexCoord2f(0.0, 0.0); */
553 /*       glVertex3f(0.5, 0.0, BOARDSIZE - 0.5 + 0.2); */
554 /*       glTexCoord2f(1.0, 0.0); */
555 /*       glVertex3f(1.5, 0.0, BOARDSIZE - 0.5 + 0.2); */
556 /*       glTexCoord2f(1.0, 1.5); */
557 /*       glVertex3f(1.5, 0.0, BOARDSIZE + 1.0 + 0.2); */
558 /*       glTexCoord2f(0.0, 1.5); */
559 /*       glVertex3f(0.5, 0.0, BOARDSIZE + 1.0 + 0.2); */
560 /*        mi->polygon_count++; */
561 /*   } */
562 
563 /*   /\* destination *\/ */
564 /*   glTexCoord2f(0.0, 0.0); */
565 /*   glVertex3f(BOARDSIZE - 2.5, elevator, -2.0 - 0.2); */
566 /*   glTexCoord2f(1.0, 0.0); */
567 /*   glVertex3f(BOARDSIZE - 1.5, elevator, -2.0 - 0.2); */
568 /*   glTexCoord2f(1.0, 1.5); */
569 /*   glVertex3f(BOARDSIZE - 1.5, elevator, -0.5 - 0.2); */
570 /*   glTexCoord2f(0.0, 1.5); */
571 /*   glVertex3f(BOARDSIZE - 2.5, elevator, -0.5 - 0.2); */
572 /*   mi->polygon_count++; */
573 
574 /*   glEnd(); */
575 
576 /*   for(i = 0; i < BOARDSIZE; ++i) */
577 /*     for(j = 0; j < BOARDSIZE; ++j) { */
578 /*       if(board[j][i]) { */
579 
580 /* 	/\* draw brushed boxtop *\/ */
581 /* 	glNormal3f(0.0, 1.0, 0.0); */
582 /* 	glTexCoord2f(0.0 + stf, 0.0 + stf); */
583 /* 	glVertex3f(i-0.5 + stf, h+0.001, j+0.5 - stf); */
584 /* 	glTexCoord2f(1.0 + stf, 0.0 + stf); */
585 /* 	glVertex3f(i+0.5 - stf, h+0.001, j+0.5 - stf); */
586 /* 	glTexCoord2f(1.0 + stf, 1.0 + stf); */
587 /* 	glVertex3f(i+0.5 - stf, h+0.001, j-0.5 + stf); */
588 /* 	glTexCoord2f(0.0 + stf, 1.0 + stf); */
589 /* 	glVertex3f(i-0.5 + stf, h+0.001, j-0.5 + stf); */
590 /*      mi->polygon_count++; */
591 /*       } */
592 /*     } */
593 
594 /*   glEnd(); */
595 }
596 
build_board(antmazestruct * mp,int b)597 static void build_board(antmazestruct *mp, int b)
598 {
599   int i, j;
600 
601   for(i = 0; i < BOARDSIZE; ++i)
602     for(j = 0; j < BOARDSIZE; ++j)
603       mp->board[b][i][j] = 1;
604 
605 /*   for(i = 0; i < BOARDSIZE; ++i) { */
606 /*     board[0][i] = 1; */
607 /*     board[i][0] = 1; */
608 /*     board[BOARDSIZE-1][BOARDSIZE-i] = 1; */
609 /*     board[BOARDSIZE-i][BOARDSIZE-1] = 1; */
610 /*   } */
611 
612 /*   board[0][BOARDSIZE-2] = 0; */
613 /*   board[BOARDSIZE-1][1] = 0; */
614 
615 
616   mp->board[b][BOARDSIZE-1][1] = 0;
617   mp->board[b][0][BOARDSIZE-2] = 0;
618 
619   /* build the ant paths */
620   if(mp->currentboard == b) {
621     for(i = 0; i < ANTCOUNT; ++i) {
622       int sx = BOARDSIZE-2;
623       int sy = 1;
624 
625       for(j = 0; ; ++j) {
626 	mp->board[b][sx][sy] = 0;
627 	mp->antpath[i][j][0] = sy - 5.0;
628 	mp->antpath[i][j][1] = sx - 5.0;
629 
630 	if(random()%2) {
631 	  if(sx > 1)
632 	    sx -= 1;
633 	  else if(sy < BOARDSIZE-2)
634 	    sy += 1;
635 	  else
636 	    break;
637 	}
638 	else {
639 	  if(sy < BOARDSIZE-2)
640 	    sy += 1;
641 	  else if(sx > 1)
642 	    sx -= 1;
643 	  else
644 	    break;
645 	}
646       }
647 
648       ++j;
649       mp->antpath[i][j][0] = BOARDSIZE-7.0;
650       mp->antpath[i][j][1] = -7.0;
651       mp->antpathlength[i] = j;
652     }
653   }
654 
655 /*   for(i = 0; i < 20; ++i) { */
656 /*     int x = 1 + random()%(BOARDSIZE-2); */
657 /*     int y = 1 + random()%(BOARDSIZE-2); */
658 /*     board[x][y] = 1; */
659 /*   } */
660 }
661 
662 /* compute nearness */
near(double a[2],double b[2])663 static int near(double a[2], double b[2])
664 {
665   return fabs(a[0] - b[0]) < 0.5 && fabs(a[1] - b[1]) < 0.5;
666 }
667 
sign(double d)668 static double sign(double d)
669 {
670   return d < 0.0 ? -1.0 : 1.0;
671 }
672 
min(double a,double b)673 static double min(double a, double b)
674 {
675   return a < b ? a : b;
676 }
677 
678 /* draw method for ant */
draw_ant(ModeInfo * mi,antmazestruct * mp,const float * Material,int mono,int shadow,float ant_step,Bool (* sphere)(float),Bool (* cone)(float))679 static Bool draw_ant(ModeInfo *mi, antmazestruct *mp,
680                      const float *Material, int mono, int shadow,
681 	      float ant_step, Bool (*sphere)(float), Bool (*cone)(float))
682 {
683 
684   float cos1 = cos(mp->ant_step);
685   float cos2 = cos(mp->ant_step + 2 * Pi / 3);
686   float cos3 = cos(mp->ant_step + 4 * Pi / 3);
687   float sin1 = sin(mp->ant_step);
688   float sin2 = sin(mp->ant_step + 2 * Pi / 3);
689   float sin3 = sin(mp->ant_step + 4 * Pi / 3);
690 
691   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mono ? MaterialGray5 : Material);
692 
693 /*   glEnable(GL_CULL_FACE); */
694 
695   glPushMatrix();
696   glScalef(1, 1.3, 1);
697   if(!((*sphere)(0.18)))
698     return False;
699   glScalef(1, 1 / 1.3, 1);
700   glTranslatef(0.00, 0.30, 0.00);
701   if(!((*sphere)(0.2)))
702     return False;
703 
704   glTranslatef(-0.05, 0.17, 0.05);
705   glRotatef(-90, 1, 0, 0);
706   glRotatef(-25, 0, 1, 0);
707   if(!((*cone)(0.05)))
708     return False;
709   glTranslatef(0.00, 0.10, 0.00);
710   if(!((*cone)(0.05)))
711     return False;
712   glRotatef(25, 0, 1, 0);
713   glRotatef(90, 1, 0, 0);
714 
715   glScalef(1, 1.3, 1);
716   glTranslatef(0.15, -0.65, 0.05);
717   if(!((*sphere)(0.25)))
718     return False;
719   glScalef(1, 1 / 1.3, 1);
720   glPopMatrix();
721 
722 /*   glDisable(GL_CULL_FACE); */
723 
724   glDisable(GL_LIGHTING);
725 
726   /* ANTENNAS */
727   glBegin(GL_LINES);
728   glColor3fv(mono ? MaterialGray5 : Material);
729   glVertex3f(0.00, 0.30, 0.00);
730   glColor3fv(MaterialGray);
731   glVertex3f(0.40, 0.70, 0.40);
732   mi->polygon_count++;
733   glColor3fv(mono ? MaterialGray5 : Material);
734   glVertex3f(0.00, 0.30, 0.00);
735   glColor3fv(MaterialGray);
736   glVertex3f(0.40, 0.70, -0.40);
737   mi->polygon_count++;
738   glEnd();
739 
740   if(!shadow) {
741     glBegin(GL_POINTS);
742     glColor3fv(mono ? MaterialGray6 : MaterialRed);
743     glVertex3f(0.40, 0.70, 0.40);
744     mi->polygon_count++;
745     glVertex3f(0.40, 0.70, -0.40);
746     mi->polygon_count++;
747     glEnd();
748   }
749 
750   /* LEFT-FRONT ARM */
751   glBegin(GL_LINE_STRIP);
752   glColor3fv(mono ? MaterialGray5 : Material);
753   glVertex3f(0.00, 0.05, 0.18);
754   glVertex3f(0.35 + 0.05 * cos1, 0.15, 0.25);
755   mi->polygon_count++;
756   glColor3fv(MaterialGray);
757   glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45);
758   mi->polygon_count++;
759   glEnd();
760 
761   /* LEFT-CENTER ARM */
762   glBegin(GL_LINE_STRIP);
763   glColor3fv(mono ? MaterialGray5 : Material);
764   glVertex3f(0.00, 0.00, 0.18);
765   glVertex3f(0.35 + 0.05 * cos2, 0.00, 0.25);
766   mi->polygon_count++;
767   glColor3fv(MaterialGray);
768   glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45);
769   mi->polygon_count++;
770   glEnd();
771 
772   /* LEFT-BACK ARM */
773   glBegin(GL_LINE_STRIP);
774   glColor3fv(mono ? MaterialGray5 : Material);
775   glVertex3f(0.00, -0.05, 0.18);
776   glVertex3f(0.35 + 0.05 * cos3, -0.15, 0.25);
777   mi->polygon_count++;
778   glColor3fv(MaterialGray);
779   glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45);
780   mi->polygon_count++;
781   glEnd();
782 
783   /* RIGHT-FRONT ARM */
784   glBegin(GL_LINE_STRIP);
785   glColor3fv(mono ? MaterialGray5 : Material);
786   glVertex3f(0.00, 0.05, -0.18);
787   glVertex3f(0.35 - 0.05 * sin1, 0.15, -0.25);
788   mi->polygon_count++;
789   glColor3fv(MaterialGray);
790   glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45);
791   mi->polygon_count++;
792   glEnd();
793 
794   /* RIGHT-CENTER ARM */
795   glBegin(GL_LINE_STRIP);
796   glColor3fv(mono ? MaterialGray5 : Material);
797   glVertex3f(0.00, 0.00, -0.18);
798   glVertex3f(0.35 - 0.05 * sin2, 0.00, -0.25);
799   mi->polygon_count++;
800   glColor3fv(MaterialGray);
801   glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45);
802   mi->polygon_count++;
803   glEnd();
804 
805   /* RIGHT-BACK ARM */
806   glBegin(GL_LINE_STRIP);
807   glColor3fv(mono ? MaterialGray5 : Material);
808   glVertex3f(0.00, -0.05, -0.18);
809   glVertex3f(0.35 - 0.05 * sin3, -0.15, -0.25);
810   mi->polygon_count++;
811   glColor3fv(MaterialGray);
812   glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45);
813   mi->polygon_count++;
814   glEnd();
815 
816   if(!shadow) {
817     glBegin(GL_POINTS);
818     glColor3fv(mono ? MaterialGray8 : MaterialGray35);
819     glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45);
820     glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45);
821     glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45);
822     glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45);
823     glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45);
824     glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45);
825     mi->polygon_count += 6;
826     glEnd();
827   }
828 
829   glEnable(GL_LIGHTING);
830 
831   return True;
832 }
833 
draw_antmaze_strip(ModeInfo * mi)834 static Bool draw_antmaze_strip(ModeInfo * mi)
835 {
836   antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
837   int i;
838   int mono = MI_IS_MONO(mi);
839 
840 /*   glMatrixMode(GL_MODELVIEW); */
841 /*   glLoadIdentity(); */
842 /*   glPushMatrix(); */
843 
844   glEnable(GL_LIGHTING);
845 /*   glDisable(GL_BLEND); */
846   glEnable(GL_LIGHT0);
847   glEnable(GL_LIGHT1);
848 
849   /* set light */
850 /*   double l1 = 1.0 - (elevator < 1.0 ? elevator : 2.0 - elevator); */
851 /*   GLfloat df[4] = {0.8*l1, 0.8*l1, 0.8*l1, 1.0}; */
852 /*   glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
853 /*   glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
854 
855   /* draw board */
856   if(mp->elevator < 1.0) {
857     glEnable(GL_TEXTURE_2D);
858     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray6);
859     glTranslatef(-(BOARDSIZE-1)/2.0, 0.0, -(BOARDSIZE-1)/2.0);
860     draw_board(mi, mp);
861     glTranslatef(BOARDSIZE/2.0, 0.0, BOARDSIZE/2.0);
862     glDisable(GL_TEXTURE_2D);
863   }
864 
865   mp->introduced--;
866 
867   glTranslatef(0.0, -0.1, 0.0);
868 
869   for(i = 0; i < ANTCOUNT; ++i) {
870 
871 /*     glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
872 /*     glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
873 
874     if(!mp->anton[i]) { continue; }
875 
876     /* determine location, move to goal */
877     glPushMatrix();
878     glTranslatef(0.0, 0.01, 0.0);
879     glTranslatef(mp->antposition[i][0], mp->antposition[i][2], mp->antposition[i][1]);
880 /*     glScalef(1.0, 0.01, 1.0); */
881     glScalef(0.6, 0.01, 0.6);
882     glRotatef(180.0 + mp->antdirection[i]*180.0/PI, 0.0, 1.0, 0.0);
883     glRotatef(90.0, 0.0, 0.0, 1.0);
884     glDisable(GL_LIGHTING);
885     glEnable(GL_BLEND);
886     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
887     glColor4fv(MaterialGrayB);
888 
889     glScalef(mp->antsize[i], mp->antsize[i], mp->antsize[i]);
890 
891     /* slow down first ant */
892     if(i == 0 && mp->part[i] == mp->antpathlength[i])
893       draw_ant(mi, mp, MaterialGrayB, mono, 1, mp->first_ant_step, mySphere, myCone);
894     else
895       draw_ant(mi, mp, MaterialGrayB, mono, 1, mp->ant_step, mySphere, myCone);
896 
897     glPopMatrix();
898 
899     glDisable(GL_BLEND);
900     glEnable(GL_LIGHTING);
901 
902     glPushMatrix();
903 /*     glTranslatef(0.0, 0.18, 0.0); */
904     glTranslatef(0.0, 0.12, 0.0);
905     glTranslatef(mp->antposition[i][0], mp->antposition[i][2], mp->antposition[i][1]);
906     glRotatef(180.0 + mp->antdirection[i]*180.0/PI, 0.0, 1.0, 0.0);
907     glRotatef(90.0, 0.0, 0.0, 1.0);
908     glScalef(0.6, 0.6, 0.6);
909 
910     glScalef(mp->antsize[i], mp->antsize[i], mp->antsize[i]);
911 
912 /*     glEnable(GL_TEXTURE_2D); */
913 /*     glBindTexture(GL_TEXTURE_2D, brushedtexture); */
914 
915 /*     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed); */
916 
917     /* slow down first ant */
918     if(i == 0 && mp->part[i] == mp->antpathlength[i] && mp->elevator > 0.0) {
919       glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
920       glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
921       draw_ant(mi, mp, antmaterial[i], mono, 1, mp->first_ant_step, mySphere, myCone);
922     }
923     else {
924 /*       glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
925 /*       glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
926 
927       glEnable(GL_TEXTURE_2D);
928       glBindTexture(GL_TEXTURE_2D, mp->brushedtexture);
929       draw_ant(mi, mp, antmaterial[i], mono, 1, mp->ant_step, mySphereTex, myCone);
930       glDisable(GL_TEXTURE_2D);
931     }
932 
933 
934 /*     draw_ant(mi, antmaterial[i], mono, 0, ant_step, mySphereTex, myCone); */
935 /*     glDisable(GL_TEXTURE_2D); */
936     glPopMatrix();
937   }
938 
939 /*   glPopMatrix(); */
940 
941 /*   /\* now draw overlay *\/ */
942 /*   glDisable(GL_LIGHTING); */
943 /*   glDisable(GL_BLEND); */
944 
945 /*   /\* go to ortho mode *\/ */
946 /*   glMatrixMode(GL_PROJECTION); */
947 /*   glPushMatrix(); */
948 /*   glLoadIdentity(); */
949 /*   glOrtho(-4.0, 4.0, -3.0, 3.0, -100.0, 100.0); */
950 
951 /*   /\* translate to corner *\/ */
952 /*   glTranslatef(4.0-1.2, 3.0-1.2, 0.0); */
953 
954 /*   glDisable(GL_LIGHTING); */
955 /*   glEnable(GL_BLEND); */
956 
957 /*   /\* draw the 2d board *\/ */
958 /*   glBegin(GL_QUADS); */
959 /*   { */
960 /*     int i, j; */
961 /*     double sz = 1.0; */
962 /*     for(i = 0; i < BOARDSIZE; ++i) */
963 /*       for(j = 0; j < BOARDSIZE; ++j) { */
964 /* 	int par = board[i][j]; */
965 /* 	glColor4f(par ? 0.4 : 0.6, */
966 /* 		  par ? 0.4 : 0.6, */
967 /* 		  par ? 0.4 : 0.6, */
968 /* 		  0.5); */
969 /* 	glNormal3f(0.0, 0.0, 1.0); */
970 /* 	glVertex3f((sz*(i+1))/BOARDSIZE,     (sz*(j+1))/BOARDSIZE, 0.0); */
971 /* 	glVertex3f((sz*i)/BOARDSIZE, (sz*(j+1))/BOARDSIZE, 0.0); */
972 /* 	glVertex3f((sz*i)/BOARDSIZE, (sz*j)/BOARDSIZE, 0.0); */
973 /* 	glVertex3f((sz*(i+1))/BOARDSIZE, (sz*j)/BOARDSIZE, 0.0); */
974 /*      mi->polygon_count++; */
975 /*       } */
976 /*   } */
977 /*   glEnd(); */
978 
979 /*   glPopMatrix(); */
980 
981 
982   /* but the step size is the same! */
983   mp->ant_step += 0.18;
984 /*   if(ant_step > 2*Pi) { */
985 /*     ant_step = 0.0; */
986 /*   } */
987 
988   if(mp->ant_step > 5*Pi)
989     mp->started = 1;
990 
991   mp->ant_position += 1;
992   return True;
993 }
994 #undef AntmazeDivisions
995 #undef AntmazeTransversals
996 
reshape_antmaze(ModeInfo * mi,int width,int height)997 ENTRYPOINT void reshape_antmaze(ModeInfo * mi, int width, int height)
998 {
999   double h = (GLfloat) height / (GLfloat) width;
1000   int size = (width / 512) + 1;
1001   antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
1002 
1003   glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
1004   glMatrixMode(GL_PROJECTION);
1005   glLoadIdentity();
1006 
1007   gluPerspective(45, 1/h, 1, 25.0);
1008 
1009   glMatrixMode(GL_MODELVIEW);
1010 /*   glLineWidth(3.0); */
1011    glLineWidth(size);
1012   glPointSize(size);
1013 }
1014 
update_ants(antmazestruct * mp)1015 static void update_ants(antmazestruct *mp)
1016 {
1017   int i;
1018   GLfloat df[4];
1019   df[0] = df[1] = df[2] = 0.8*mp->fadeout;
1020   df[3] = 1.0;
1021 
1022   /* fade out */
1023   if(mp->fadeoutspeed < -0.00001) {
1024 
1025     if(mp->fadeout <= 0.0) {
1026       /* switch boards: rebuild old board, increment current */
1027       mp->currentboard = (mp->currentboard+1)%BOARDCOUNT;
1028       build_board(mp, mp->currentboard);
1029       mp->fadeoutspeed = 0.02;
1030     }
1031 
1032     mp->fadeout += mp->fadeoutspeed;
1033 
1034     glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
1035     glLightfv(GL_LIGHT1, GL_DIFFUSE, df);
1036   }
1037 
1038   /* fade in */
1039   if(mp->fadeoutspeed > 0.0001) {
1040     mp->fadeout += mp->fadeoutspeed;
1041     if(mp->fadeout >= 1.0) {
1042       mp->fadeout = 1.0;
1043       mp->fadeoutspeed = 0.0;
1044       mp->entroducing = 12;
1045     }
1046     glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
1047     glLightfv(GL_LIGHT1, GL_DIFFUSE, df);
1048   }
1049 
1050   for(i = 0; i < ANTCOUNT; ++i) {
1051 
1052     if(!mp->anton[i] && mp->elevator < 1.0) {
1053 
1054       /* turn on ant */
1055       if(mp->entroducing > 0 && mp->introduced <= 0 && random()%100 == 0) {
1056 	mp->anton[i] = 1;
1057 	mp->part[i] = 0;
1058 	mp->antsize[i] = 0.0;
1059 	mp->antposition[i][0] = -4.0;
1060 	mp->antposition[i][1] = 5.0;
1061 	mp->antdirection[i] = PI/2.0;
1062 	mp->bposition[i][0] = 0;
1063 	mp->bposition[i][1] = 8;
1064 	mp->introduced = 300;
1065 	mp->entroducing--;
1066       }
1067 
1068       continue;
1069     }
1070 
1071     if(mp->part[i] == 0 && mp->antsize[i] < 1.0) {
1072       mp->antsize[i] += 0.02;
1073       continue;
1074     }
1075 
1076     if(mp->part[i] > mp->antpathlength[i] && mp->antsize[i] > 0.0) {
1077       mp->antsize[i] -= 0.02;
1078       if(mp->antvelocity[i] > 0.0) {
1079 	mp->antvelocity[i] -= 0.02;
1080       }
1081       else { mp->antvelocity[i] = 0.0; }
1082 
1083       continue;
1084     }
1085 
1086     if(mp->part[i] > mp->antpathlength[i] && mp->antsize[i] <= 0.0) {
1087       mp->antvelocity[i] = 0.02;
1088 
1089       /* 	if(i != 0) { */
1090       antmaterial[i] = materials[random()%MATERIALS];
1091       /* 	} */
1092 
1093       mp->antdirection[i] = PI/2.0;
1094       mp->bposition[i][0] = 0;
1095       mp->bposition[i][1] = 8;
1096       mp->part[i] = 0;
1097 
1098       mp->antsize[i] = 0.0;
1099 
1100       mp->anton[i] = 0;
1101 
1102       mp->antposition[i][0] = -4.0;
1103       mp->antposition[i][1] = 5.0;
1104 
1105       /* 	/\* reset camera *\/ */
1106       /* 	if(i == focus) { */
1107       /* 	  started = 0; */
1108       /* 	  ant_step = 0.0; */
1109       /* 	} */
1110 
1111       /* check for the end */
1112       if(mp->entroducing <= 0) {
1113 	int ao = 0, z = 0;
1114 	for(z = 0; z < ANTCOUNT; ++z) {
1115 	  if(mp->anton[z]) { ao = 1; break; }
1116 	}
1117 
1118 	if(ao == 0) {
1119 	  mp->fadeoutspeed = -0.02;
1120 	}
1121       }
1122 
1123     }
1124 
1125     /* near goal, bend path towards next step */
1126     if(near(mp->antposition[i], mp->antpath[i][mp->part[i]])) {
1127 
1128       ++mp->part[i];
1129 
1130 /*       /\* special first ant *\/ */
1131 /*       if(i == 0 && part[i] > antpathlength[i]) { */
1132 /* 	if(fir) */
1133 /* 	  first_ant_step = ant_step; */
1134 
1135 /* 	antvelocity[i] = 0.0; */
1136 /* /\* 	antposition[i][2] += 0.025; *\/ */
1137 /* 	elevator += 0.025; */
1138 
1139 /* 	/\* set light *\/ */
1140 /* 	double l1 = 1.0 - (elevator < 1.0 ? elevator : 2.0 - elevator); */
1141 /* 	GLfloat df[4] = {0.8*l1, 0.8*l1, 0.8*l1, 1.0}; */
1142 /* 	glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
1143 /* 	glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
1144 
1145 /* 	/\* draw next board *\/ */
1146 /* 	if(elevator > 1.0) { */
1147 
1148 /* 	  if(makenew == 1) { */
1149 /* 	    int re; */
1150 
1151 /* 	    /\* switch boards: rebuild old board, increment current *\/ */
1152 /* 	    currentboard = (currentboard+1)%BOARDCOUNT; */
1153 /* 	    build_board(currentboard); */
1154 
1155 /* 	    for(re = 1; re < ANTCOUNT; ++re) { */
1156 /* 	      anton[re] = 0; */
1157 /* 	      antmaterial[re] = materials[random()%MATERIALS]; */
1158 /* 	    } */
1159 
1160 /* 	    makenew = 0; */
1161 
1162 /* 	  } */
1163 
1164 /* 	  /\* draw the other board *\/ */
1165 /* 	  glEnable(GL_TEXTURE_2D); */
1166 /* 	  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray6); */
1167 
1168 /* 	  glPushMatrix(); */
1169 /* 	  glTranslatef(-(-(BOARDSIZE-3.5)+(BOARDSIZE-1)/2.0), 0.0,  */
1170 /* 		       -(2.4+BOARDSIZE+(BOARDSIZE-1)/2.0)); */
1171 /* 	  draw_board(mi, mp); */
1172 /* 	  glPopMatrix(); */
1173 /* 	  glDisable(GL_TEXTURE_2D); */
1174 /* 	} */
1175 /* 	/\* reset *\/ */
1176 /* 	if(elevator > 2.0) { */
1177 /* 	  antposition[i][0] = -4.0;/\*-= -(-(BOARDSIZE-3.5)+(BOARDSIZE-1)/2.0);*\//\*= -4.0;*\/ */
1178 /* 	  antposition[i][1] = 5.5;/\*-(2.4+BOARDSIZE+(BOARDSIZE-1)/2.0);*\/ */
1179 /* /\* 	  antposition[i][2] = 0.15; *\/ */
1180 /* 	  antdirection[i] = PI/2.0; */
1181 /* 	  bposition[i][0] = 0; */
1182 /* 	  bposition[i][1] = 8; */
1183 /* 	  part[i] = 0; */
1184 /* 	  antvelocity[i] = 0.02; */
1185 /* 	  fir = 0; */
1186 /* 	  antmaterial[i] = MaterialRed; */
1187 
1188 /* 	  makenew = 1; */
1189 
1190 /* 	  elevator = 0.0; */
1191 /* 	  introduced = 200; */
1192 /* 	} */
1193 /* 	else { */
1194 /* 	  part[i]--; */
1195 /* 	} */
1196 /*       } */
1197 
1198     }
1199 
1200     /* move toward goal, correct ant direction if required */
1201     else {
1202 
1203       /* difference */
1204       double dx = mp->antpath[i][mp->part[i]][0] - mp->antposition[i][0];
1205       double dz = - mp->antpath[i][mp->part[i]][1] + mp->antposition[i][1];
1206       double theta, ideal;
1207 
1208       if(dz > EPSILON)
1209 	theta = atan(dz/dx);
1210       else
1211 	theta = dx > EPSILON ? 0.0 : PI;
1212 
1213       ideal = theta - mp->antdirection[i];
1214       if(ideal < -Pi/2.0)
1215 	ideal += Pi;
1216 
1217       /* compute correction */
1218       {
1219         double dt = sign(ideal) * min(fabs(ideal), PI/90.0);
1220         mp->antdirection[i] += dt;
1221         if(mp->antdirection[i] > 2.0*PI)
1222           mp->antdirection[i] = 0.0;
1223       }
1224     }
1225 
1226     mp->antposition[i][0] += mp->antvelocity[i] * cos(mp->antdirection[i]);
1227     mp->antposition[i][1] += mp->antvelocity[i] * sin(-mp->antdirection[i]);
1228   }
1229 }
1230 
pinit(antmazestruct * mp)1231 static void pinit(antmazestruct *mp)
1232 {
1233   glClearDepth(1.0);
1234   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1235   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
1236   glLightfv(GL_LIGHT0, GL_POSITION, position0);
1237   glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1238   glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
1239   glLightfv(GL_LIGHT1, GL_POSITION, position1);
1240 
1241   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
1242   glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.001);
1243   glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
1244 
1245   glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.05);
1246   glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.001);
1247   glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.1);
1248 
1249 
1250 /*   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); */
1251 /*   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); */
1252   glEnable(GL_LIGHTING);
1253   glEnable(GL_LIGHT0);
1254   glEnable(GL_LIGHT1);
1255   glEnable(GL_NORMALIZE);
1256   glFrontFace(GL_CCW);
1257   glCullFace(GL_BACK);
1258 
1259   /* antmaze */
1260   glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
1261   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
1262 
1263   glShadeModel(GL_SMOOTH);
1264   glEnable(GL_DEPTH_TEST);
1265   glDisable(GL_TEXTURE_2D);
1266 
1267   /* setup textures */
1268   makeCheckImage(mp);
1269   makeBrushedImage(mp);
1270 
1271   build_board(mp, 0);
1272   build_board(mp, 1);
1273 
1274 /*   makeCheckImage(); */
1275 /*   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); */
1276 /*   glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,  */
1277 /* 	       checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, checkers); */
1278 /*   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); */
1279 /*   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); */
1280 
1281 /*   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); */
1282 /*   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); */
1283 /*   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */
1284   glEnable(GL_TEXTURE_2D);
1285 
1286 /*   glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess); */
1287 /*   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); */
1288 }
1289 
1290 #define MAX_MAGNIFICATION 10
1291 #define max(a, b) a < b ? b : a
1292 #define min(a, b) a < b ? a : b
1293 
antmaze_handle_event(ModeInfo * mi,XEvent * event)1294 ENTRYPOINT Bool antmaze_handle_event (ModeInfo *mi, XEvent *event)
1295 {
1296   antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
1297 
1298   if (gltrackball_event_handler (event, mp->trackball,
1299                                  MI_WIDTH (mi), MI_HEIGHT (mi),
1300                                  &mp->button_down_p))
1301     return True;
1302 
1303   if (event->xany.type == ButtonPress)
1304     {
1305       switch(event->xbutton.button) {
1306 
1307       case Button3:
1308         mp->focus = (mp->focus + 1) % ANTCOUNT;
1309         return True;
1310 
1311       case Button4:
1312         mp->mag = max(mp->mag-1, 1);
1313         return True;
1314 
1315       case Button5:
1316         mp->mag = min(mp->mag+1, MAX_MAGNIFICATION);
1317         return True;
1318       }
1319     }
1320 
1321   return False;
1322 }
1323 
init_antmaze(ModeInfo * mi)1324 ENTRYPOINT void init_antmaze(ModeInfo * mi)
1325 {
1326   double rot_speed = 0.3;
1327   int i;
1328 
1329   antmazestruct *mp;
1330 
1331   MI_INIT(mi, antmaze);
1332   mp = &antmaze[MI_SCREEN(mi)];
1333   mp->step = NRAND(90);
1334   mp->ant_position = NRAND(90);
1335 
1336 
1337   mp->antdirection[0] = PI/2.0;
1338   mp->antdirection[1] = PI/2.0;
1339   mp->antdirection[2] = 0;
1340   mp->antdirection[3] = PI/2.0;
1341   mp->antdirection[4] = PI/2.0;
1342 
1343   mp->antposition[0][0] = -4.0;
1344   mp->antposition[0][1] =  5.0;
1345   mp->antposition[0][1] =  0.15;
1346 
1347   mp->antposition[1][0] = -4.0;
1348   mp->antposition[1][1] =  3.0;
1349   mp->antposition[1][1] =  0.15;
1350 
1351   mp->antposition[2][0] = -1.0;
1352   mp->antposition[2][1] = -2.0;
1353   mp->antposition[2][1] =  0.15;
1354 
1355   mp->antposition[3][0] = -3.9;
1356   mp->antposition[3][1] =  6.0;
1357   mp->antposition[3][1] =  0.15;
1358 
1359   mp->antposition[4][0] =  2.0;
1360   mp->antposition[4][1] = -2.0;
1361   mp->antposition[4][1] =  0.15;
1362 
1363 
1364 
1365   for (i = 0; i < ANTCOUNT; i++) {
1366     mp->antvelocity[i] = 0.02;
1367     mp->antsize[i] = 1.0;
1368     mp->anton[i] = 0;
1369   }
1370 
1371   mp->bposition[0][0] = 0;
1372   mp->bposition[0][1] = 8;
1373 
1374   mp->bposition[1][0] = 9;
1375   mp->bposition[1][1] = 1;
1376 
1377   mp->bposition[2][0] = 1;
1378   mp->bposition[2][1] = 1;
1379 
1380   mp->bposition[3][0] = 4;
1381   mp->bposition[3][1] = 8;
1382 
1383   mp->bposition[4][0] = 2;
1384   mp->bposition[4][1] = 1;
1385 
1386   mp->part[0] = 0;
1387   mp->part[1] = 1;
1388   mp->part[2] = 5;
1389   mp->part[3] = 1;
1390   mp->part[4] = 3;
1391 
1392   mp->introduced = 0;
1393   mp->entroducing = 12;
1394   mp->fadeout = 1.0;
1395   mp->mag = 4.0;
1396 
1397   mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
1398   mp->trackball = gltrackball_init (False);
1399 
1400   if ((mp->glx_context = init_GL(mi)) != NULL) {
1401     reshape_antmaze(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
1402     glDrawBuffer(GL_BACK);
1403     pinit(mp);
1404   }
1405   else
1406     MI_CLEARWINDOW(mi);
1407 }
1408 
1409 static void
device_rotate(ModeInfo * mi)1410 device_rotate(ModeInfo *mi)
1411 {
1412 #if 0
1413   GLfloat rot = current_device_rotation();
1414   glRotatef(rot, 0, 0, 1);
1415   if ((rot >  45 && rot <  135) ||
1416       (rot < -45 && rot > -135))
1417     {
1418       GLfloat s = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
1419       glScalef (1/s, s, 1);
1420     }
1421 #endif
1422 }
1423 
1424 
draw_antmaze(ModeInfo * mi)1425 ENTRYPOINT void draw_antmaze(ModeInfo * mi)
1426 {
1427   double h = (GLfloat) MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
1428 
1429   antmazestruct *mp;
1430 
1431   Display    *display = MI_DISPLAY(mi);
1432   Window      window = MI_WINDOW(mi);
1433 
1434   if(!antmaze)
1435 	return;
1436   mp = &antmaze[MI_SCREEN(mi)];
1437 
1438   MI_IS_DRAWN(mi) = True;
1439 
1440   if(!mp->glx_context)
1441 	return;
1442 
1443   mi->polygon_count = 0;
1444   glXMakeCurrent(display, window, *mp->glx_context);
1445 
1446   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1447 
1448   /* first panel */
1449   glPushMatrix();
1450 /*   h = ((GLfloat) MI_HEIGHT(mi)/2) / (3*(GLfloat)MI_WIDTH(mi)/4); */
1451   glViewport(MI_WIDTH(mi)/32, MI_HEIGHT(mi)/8, (9*MI_WIDTH(mi))/16, 3*MI_HEIGHT(mi)/4);
1452   glMatrixMode(GL_PROJECTION);
1453   glLoadIdentity();
1454 
1455 /*   h = (3*MI_HEIGHT(mi)/4) / (3*MI_WIDTH(mi)/4); */
1456   gluPerspective(45, 1/h, 1, 25.0);
1457 
1458   glMatrixMode(GL_MODELVIEW);
1459   glLoadIdentity();
1460   device_rotate(mi);
1461 
1462   glPushMatrix();
1463 
1464   /* follow focused ant */
1465   glTranslatef(0.0, 0.0, -mp->mag - 5.0);
1466   glRotatef(20.0+5.0*sin(mp->ant_step/40.0), 1.0, 0.0, 0.0);
1467 /*   glTranslatef(0.0,  */
1468 /* 	       started ? -mag : -8.0 + 4.0*fabs(sin(ant_step/10.0)),  */
1469 /* 	       started ? -mag : -8.0 + 4.0*fabs(sin(ant_step/10.0))); */
1470 
1471   gltrackball_rotate(mp->trackball);
1472 
1473   glRotatef(mp->ant_step*0.6, 0.0, 1.0, 0.0);
1474 
1475 /*   glRotatef(90.0, 0.0, 0.0, 1.0); */
1476 
1477 /*   glTranslatef(-antposition[0][0]-0.5, 0.0, -antposition[focus][1]); */
1478   /*-elevator*/
1479 
1480   /* sync */
1481   if(!draw_antmaze_strip(mi)) {
1482     MI_ABORT(mi);
1483     return;
1484   }
1485 
1486   glPopMatrix();
1487   glPopMatrix();
1488 
1489   h = (GLfloat) (3*MI_HEIGHT(mi)/8) / (GLfloat) (MI_WIDTH(mi)/2);
1490 
1491   /* draw overhead */
1492   glPushMatrix();
1493   glViewport((17*MI_WIDTH(mi))/32, MI_HEIGHT(mi)/2, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8);
1494   glMatrixMode(GL_PROJECTION);
1495   glLoadIdentity();
1496   device_rotate(mi);
1497   gluPerspective(45, 1/h, 1, 25.0);
1498   glMatrixMode(GL_MODELVIEW);
1499 
1500   /* twist scene */
1501   glTranslatef(0.0, 0.0, -16.0);
1502   glRotatef(60.0, 1.0, 0.0, 0.0);
1503   glRotatef(-15.0 + mp->ant_step/10.0, 0.0, 1.0, 0.0);
1504   gltrackball_rotate(mp->trackball);
1505 
1506   /* sync */
1507   if(!draw_antmaze_strip(mi)) {
1508     MI_ABORT(mi);
1509     return;
1510   }
1511 
1512   glPopMatrix();
1513 
1514   /* draw ant display */
1515   glPushMatrix();
1516   glViewport((5*MI_WIDTH(mi))/8, MI_HEIGHT(mi)/8, (11*MI_WIDTH(mi))/32, 3*MI_HEIGHT(mi)/8);
1517   glMatrixMode(GL_PROJECTION);
1518   glLoadIdentity();
1519   device_rotate(mi);
1520   gluPerspective(45, 1/h, 1, 25.0);
1521   glMatrixMode(GL_MODELVIEW);
1522 
1523   /* twist scene */
1524   glTranslatef(0.0, 0.0, -1.6);
1525   glRotatef(30.0, 1.0, 0.0, 0.0);
1526   glRotatef(mp->ant_step, 0.0, 1.0, 0.0);
1527   glRotatef(90.0, 0.0, 0.0, 1.0);
1528 
1529 /*   /\* draw ant shadow *\/ */
1530 /*   glPushMatrix(); */
1531 /*   glScalef(1.0, 0.01, 1.0); */
1532 /*   glRotatef(90.0, 0.0, 0.0, 1.0); */
1533 /*   glRotatef(90.0, 0.0, 1.0, 0.0); */
1534 /*   glDisable(GL_LIGHTING); */
1535 /*   glColor4fv(MaterialGray6); */
1536 
1537 /*   /\* slow down first ant *\/ */
1538 /*   draw_ant(MaterialGrayB, 0, 1, first_ant_step, mySphere, myCone); */
1539 /*   glPopMatrix(); */
1540 
1541   /* draw ant body */
1542   glEnable(GL_TEXTURE_2D);
1543   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
1544   glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
1545   glBindTexture(GL_TEXTURE_2D, mp->brushedtexture);
1546   draw_ant(mi, mp, MaterialGray35, 0, 1, mp->ant_step/2.0, mySphereTex, myCone2);
1547   glDisable(GL_TEXTURE_2D);
1548 
1549   glPopMatrix();
1550 
1551 /*   /\* draw overlay *\/ */
1552 /*   glPushMatrix(); */
1553 
1554 /*   /\* go to ortho mode *\/ */
1555 /*   glViewport(MI_WIDTH(mi)/2, MI_HEIGHT(mi)/8, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8); */
1556 
1557 /*   glMatrixMode(GL_PROJECTION); */
1558 /*   glLoadIdentity(); */
1559 
1560 /*   glPushMatrix (); */
1561 /*   glOrtho(-4.0, 4.0, -3.0, 3.0, -100.0, 100.0); */
1562 
1563 /*   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGrayB); */
1564 /*   glColor4fv(MaterialGrayB); */
1565 
1566 /*   glDisable(GL_LIGHTING); */
1567 /*   glEnable(GL_BLEND); */
1568 
1569 /*   glBegin(GL_QUADS); */
1570 /*   glNormal3f(0.0, 0.0, 1.0); */
1571 /*   glVertex3f(4.0, 3.0, 0.0); */
1572 /*   glVertex3f(2.0, 3.0, 0.0); */
1573 /*   glVertex3f(2.0, -3.0, 0.0); */
1574 /*   glVertex3f(4.0, -3.0, 0.0); */
1575 /*   mi->polygon_count++; */
1576 /*   glEnd(); */
1577 
1578 /*   glEnable(GL_LIGHTING); */
1579 /*   glDisable(GL_BLEND); */
1580 
1581 /*   glPopMatrix(); */
1582 /*   glPopMatrix(); */
1583 
1584   if (MI_IS_FPS(mi)) {
1585     glViewport(0, 0, MI_WIDTH(mi), MI_HEIGHT(mi));
1586     do_fps (mi);
1587   }
1588   glFlush();
1589 
1590   glXSwapBuffers(display, window);
1591 
1592   update_ants(mp);
1593 
1594   mp->step += 0.025;
1595 }
1596 
1597 #ifndef STANDALONE
change_antmaze(ModeInfo * mi)1598 ENTRYPOINT void change_antmaze(ModeInfo * mi)
1599 {
1600   antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
1601 
1602   if (!mp->glx_context)
1603 	return;
1604 
1605   glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *mp->glx_context);
1606   pinit();
1607 }
1608 #endif /* !STANDALONE */
1609 
free_antmaze(ModeInfo * mi)1610 ENTRYPOINT void free_antmaze(ModeInfo * mi)
1611 {
1612   antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
1613   if (!mp->glx_context) return;
1614   glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *mp->glx_context);
1615   gltrackball_free (mp->trackball);
1616   free_rotator (mp->rot);
1617   if (mp->checktexture) glDeleteTextures (1, &mp->checktexture);
1618   if (mp->brushedtexture) glDeleteTextures (1, &mp->brushedtexture);
1619 }
1620 
1621 XSCREENSAVER_MODULE ("AntMaze", antmaze)
1622 
1623 #endif
1624