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