summaryrefslogtreecommitdiffstats
path: root/hacks/glx/antmaze.c
diff options
context:
space:
mode:
authorSimon Rettberg2018-10-16 10:08:48 +0200
committerSimon Rettberg2018-10-16 10:08:48 +0200
commitd3a98cf6cbc3bd0b9efc570f58e8812c03931c18 (patch)
treecbddf8e50f35a9c6e878a5bfe3c6d625d99e12ba /hacks/glx/antmaze.c
downloadxscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.gz
xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.tar.xz
xscreensaver-d3a98cf6cbc3bd0b9efc570f58e8812c03931c18.zip
Original 5.40
Diffstat (limited to 'hacks/glx/antmaze.c')
-rw-r--r--hacks/glx/antmaze.c1613
1 files changed, 1613 insertions, 0 deletions
diff --git a/hacks/glx/antmaze.c b/hacks/glx/antmaze.c
new file mode 100644
index 0000000..79b7e0b
--- /dev/null
+++ b/hacks/glx/antmaze.c
@@ -0,0 +1,1613 @@
+/*
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind. The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof. In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ * Copyright 2004 Blair Tennessy
+ * tennessy@cs.ubc.ca
+ */
+
+#if 0
+static const char sccsid[] = "@(#)antmaze.c 5.01 2001/03/01 xlockmore";
+#endif
+
+#ifdef STANDALONE
+# define MODE_antmaze
+# define DEFAULTS "*delay: 20000 \n" \
+ "*showFPS: False \n" \
+ "*fpsSolid: True \n"
+
+# define free_antmaze 0
+# define release_antmaze 0
+# include "xlockmore.h" /* from the xscreensaver distribution */
+#else /* !STANDALONE */
+# include "xlock.h" /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef HAVE_JWXYZ
+# include "jwxyz.h"
+#else
+# include <X11/Xlib.h>
+# include <GL/gl.h>
+# include <GL/glu.h>
+#endif
+
+#ifdef HAVE_JWZGLES
+# include "jwzgles.h"
+#endif /* HAVE_JWZGLES */
+
+#ifdef MODE_antmaze
+
+
+#include "sphere.h"
+#include "tube.h"
+#include "rotator.h"
+#include "gltrackball.h"
+
+#define DEF_SOLIDANTMAZE "False"
+#define DEF_NOANTS "False"
+
+static int solidantmaze;
+static int noants;
+
+static XrmOptionDescRec opts[] =
+{
+ {"-solidantmaze", ".antmaze.solidantmaze", XrmoptionNoArg, "on"},
+ {"+solidantmaze", ".antmaze.solidantmaze", XrmoptionNoArg, "off"},
+ {"-noants", ".antmaze.noants", XrmoptionNoArg, "on"},
+ {"+noants", ".antmaze.noants", XrmoptionNoArg, "off"}
+};
+static argtype vars[] =
+{
+ {&solidantmaze, "solidantmaze", "Solidantmaze", DEF_SOLIDANTMAZE, t_Bool},
+ {&noants, "noants", "Noants", DEF_NOANTS, t_Bool}
+};
+
+static OptionStruct desc[] =
+{
+ {"-/+solidantmaze", "select between a SOLID or a NET Antmaze Strip"},
+ {"-/+noants", "turn on/off walking ants"}
+};
+
+ENTRYPOINT ModeSpecOpt antmaze_opts =
+{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
+
+#ifdef USE_MODULES
+ModStruct antmaze_description =
+{"antmaze", "init_antmaze", "draw_antmaze", NULL,
+ "draw_antmaze", "change_antmaze", NULL, &antmaze_opts,
+ 1000, 1, 1, 1, 4, 1.0, "",
+ "draws some ants", 0, NULL};
+
+#endif
+
+#define Scale4Window 0.3
+#define Scale4Iconic 0.4
+
+#define sqr(A) ((A)*(A))
+
+#ifndef Pi
+#define Pi M_PI
+#endif
+
+#define ObjAntmazeStrip 0
+#define ObjAntBody 1
+#define MaxObj 2
+
+/*************************************************************************/
+
+#include "ants.h"
+
+#define ANTCOUNT 5
+#define PI 3.14157
+
+#define EPSILON 0.01
+#define BOARDSIZE 10
+#define BOARDCOUNT 2
+#define PARTS 20
+
+#define checkImageWidth 64
+#define checkImageHeight 64
+
+typedef struct {
+ GLint WindH, WindW;
+ GLfloat step;
+ GLfloat ant_position;
+ GLXContext *glx_context;
+ rotator *rot;
+ trackball_state *trackball;
+ Bool button_down_p;
+
+ int focus;
+ int currentboard;
+
+ double antdirection[ANTCOUNT];
+ double antposition[ANTCOUNT][3];
+ int anton[ANTCOUNT];
+
+ double antvelocity[ANTCOUNT];
+ double antsize[ANTCOUNT];
+ int bposition[ANTCOUNT][2];
+ int board[BOARDCOUNT][10][10];
+
+ int part[ANTCOUNT];
+ double antpath[ANTCOUNT][PARTS][2];
+ int antpathlength[ANTCOUNT];
+
+ GLubyte checkers[checkImageWidth][checkImageHeight][3];
+
+ GLuint checktexture, brushedtexture;
+ double elevator;
+
+ double ant_step;
+ double first_ant_step;
+ int started;
+ int introduced;
+ int entroducing;
+
+ double fadeout;
+ double fadeoutspeed;
+
+ int mag;
+
+} antmazestruct;
+
+static antmazestruct *antmaze = (antmazestruct *) NULL;
+
+
+static const GLfloat MaterialRed[] = {0.6, 0.0, 0.0, 1.0};
+/*static const GLfloat MaterialMagenta[] = {0.6, 0.2, 0.5, 1.0};*/
+static const GLfloat MaterialGray8[] = {0.8, 0.8, 0.8, 1.0};
+static const GLfloat MaterialGray35[] = {0.30, 0.30, 0.30, 1.0};
+static const GLfloat MaterialGray4[] = {0.40, 0.40, 0.40, 1.0};
+static const GLfloat MaterialOrange[] = {1.0, 0.69, 0.00, 1.0};
+static const GLfloat MaterialGreen[] = {0.1, 0.4, 0.2, 1.0};
+
+/* lighting variables */
+static const GLfloat front_shininess[] = {60.0};
+static const GLfloat front_specular[] = {0.8, 0.8, 0.8, 1.0};
+static const GLfloat ambient[] = {0.1, 0.1, 0.1, 1.0};
+/*static const GLfloat ambient2[] = {0.0, 0.0, 0.0, 0.0};*/
+static const GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0};
+static const GLfloat position0[] = {1.0, 5.0, 1.0, 1.0};
+static const GLfloat position1[] = {-1.0, -5.0, 1.0, 1.0};
+/*static const GLfloat lmodel_ambient[] = {0.8, 0.8, 0.8, 1.0};*/
+/*static const GLfloat lmodel_twoside[] = {GL_TRUE};*/
+/*static const GLfloat spotlight_ambient[] = { 0.0, 0.0, 0.0, 1.0 };*/
+/*static const GLfloat spotlight_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };*/
+
+#define NUM_SCENES 2
+
+/* filled sphere */
+static Bool mySphere(float radius)
+{
+#if 0
+ GLUquadricObj *quadObj;
+
+ if((quadObj = gluNewQuadric()) == 0)
+ return False;
+ gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
+ gluSphere(quadObj, radius, 16, 16);
+ gluDeleteQuadric(quadObj);
+#else
+ glPushMatrix();
+ glScalef (radius, radius, radius);
+ glRotatef (90, 1, 0, 0);
+ unit_sphere (16, 16, False);
+ glPopMatrix();
+#endif
+ return True;
+}
+
+#if 0
+/* silhouette sphere */
+static Bool mySphere2(float radius)
+{
+ GLUquadricObj *quadObj;
+
+ if((quadObj = gluNewQuadric()) == 0)
+ return False;
+ gluQuadricDrawStyle(quadObj, (GLenum) GLU_SILHOUETTE);
+ gluSphere(quadObj, radius, 16, 8);
+ gluDeleteQuadric(quadObj);
+
+ return True;
+}
+#endif
+
+/* textured sphere */
+static Bool mySphereTex(float radius)
+{
+#if 0
+ GLUquadricObj *quadObj;
+
+ if((quadObj = gluNewQuadric()) == 0)
+ return False;
+ gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
+ gluQuadricTexture(quadObj, GL_TRUE);
+ gluQuadricNormals(quadObj, GLU_SMOOTH);
+ gluSphere(quadObj, radius, 32, 16);
+ gluDeleteQuadric(quadObj);
+#else
+ glPushMatrix();
+ glScalef (radius, radius, radius);
+ glRotatef (90, 1, 0, 0);
+ unit_sphere (32, 16, False);
+ glPopMatrix();
+#endif
+
+ return True;
+}
+
+/* filled cone */
+static Bool myCone(float radius)
+{
+#if 0
+ GLUquadricObj *quadObj;
+
+ if ((quadObj = gluNewQuadric()) == 0)
+ return False;
+ gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
+ gluCylinder(quadObj, radius, 0, radius * 2, 8, 1);
+ gluDeleteQuadric(quadObj);
+#else
+ cone (0, 0, 0,
+ 0, 0, radius * 2,
+ radius, 0,
+ 8, True, True, False);
+#endif
+ return True;
+}
+
+/* no cone */
+static Bool myCone2(float radius) { return True; }
+
+#define MATERIALS 4
+static const float *antmaterial[ANTCOUNT] =
+ {MaterialRed, MaterialGray35, MaterialGray4, MaterialOrange, MaterialGreen};
+
+static const float *materials[MATERIALS] =
+ {MaterialRed, MaterialGray35, MaterialGray4, MaterialOrange};
+
+
+static void makeCheckImage(antmazestruct *mp)
+{
+ int i, j;
+
+ for (i = 0; i < checkImageWidth; i++) {
+ for (j = 0; j < checkImageHeight; j++) {
+ if(((((i&0x8)==0)^((j&0x8)))==0)) {
+ int c = 102 + random()%32;
+ mp->checkers[i][j][0] = c;
+ mp->checkers[i][j][1] = c;
+ mp->checkers[i][j][2] = c;
+ }
+ else {
+ int c = 153 + random()%32;
+ mp->checkers[i][j][0] = c;/*153;*/
+ mp->checkers[i][j][1] = c;/*c;*//*0;*/
+ mp->checkers[i][j][2] = c;/*c;*//*0;*/
+ }
+ }
+ }
+
+ glGenTextures(1, &mp->checktexture);
+ glBindTexture(GL_TEXTURE_2D, mp->checktexture);
+
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
+ checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
+ &mp->checkers[0][0]);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+static void makeBrushedImage(antmazestruct *mp)
+{
+ int i, j, c;
+
+ for(i = 0; i < checkImageWidth; ++i)
+ for(j = 0; j < checkImageHeight; ++j) {
+
+ c = 102+102*fabs(sin(2.0*i / Pi)*sin(2.0*j/Pi)) + random()%51;
+
+/* c = (i+j)%8==0 || (i+j+5)%8==0 ? 153 : 102; */
+
+ mp->checkers[i][j][0] = c;
+ mp->checkers[i][j][1] = c;
+ mp->checkers[i][j][2] = c;
+ }
+
+/* for (i = 0; i < checkImageWidth; i++) { */
+/* for (j = 0; j < checkImageHeight; j++) { */
+/* int c = 102 + pow((random()%1000)/1000.0, 4)*103; */
+/* checkers[i][j][0] = c; */
+/* checkers[i][j][1] = c; */
+/* checkers[i][j][2] = c; */
+/* } */
+/* } */
+
+/* /\* smooth *\/ */
+/* for (i = 0; i < checkImageWidth; i++) { */
+/* for (j = 0; j < checkImageHeight; j++) { */
+/* int a = checkers[(i+checkImageWidth+1)%checkImageWidth][j][0] + */
+/* 4*checkers[i][j][0] + checkers[(i+1)%checkImageWidth][j][0]; */
+/* a /= 6; */
+/* checkers[i][j][0] = a; */
+/* checkers[i][j][1] = a; */
+/* checkers[i][j][2] = a; */
+/* } */
+/* } */
+
+ glGenTextures(1, &mp->brushedtexture);
+ glBindTexture(GL_TEXTURE_2D, mp->brushedtexture);
+
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
+ checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
+ &mp->checkers[0][0]);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+#if 0
+static void draw_wall(ModeInfo *mi, double x1, double z1, double x2, double z2)
+{
+ float x = fabs(x2 - x1)/2.0;
+
+ glBegin(GL_QUADS);
+
+ /* draw top */
+ glNormal3f(0.0, 1.0, 0.0);
+ glTexCoord2f(0.0, 0.0);
+ glVertex3f(x1, 1.0, z1+0.25);
+ glTexCoord2f(x, 0.0);
+ glVertex3f(x2, 1.0, z2+0.25);
+ glTexCoord2f(x, 0.25);
+ glVertex3f(x2, 1.0, z2-0.25);
+ glTexCoord2f(0.0, 0.25);
+ glVertex3f(x1, 1.0, z1-0.25);
+ mi->polygon_count++;
+
+ /* draw sides */
+ glNormal3f(0.0, 0.0, 1.0);
+ glTexCoord2f(0.0, 0.0);
+ glVertex3f(x1, 0.0, z1+0.25);
+ glTexCoord2f(x, 0.0);
+ glVertex3f(x2, 0.0, z2+0.25);
+ glTexCoord2f(x, 0.5);
+ glVertex3f(x2, 1.0, z2+0.25);
+ glTexCoord2f(0.0, 0.5);
+ glVertex3f(x1, 1.0, z1+0.25);
+ mi->polygon_count++;
+
+ glNormal3f(0.0, 0.0, -1.0);
+ glTexCoord2f(0.0, 0.0);
+ glVertex3f(x1, 0.0, z1-0.25);
+ glTexCoord2f(x, 0.0);
+ glVertex3f(x2, 0.0, z2-0.25);
+ glTexCoord2f(x, 0.5);
+ glVertex3f(x2, 1.0, z2-0.25);
+ glTexCoord2f(0.0, 0.5);
+ glVertex3f(x1, 1.0, z1-0.25);
+ mi->polygon_count++;
+
+ /* draw ends */
+ glNormal3f(1.0, 0.0, 0.0);
+ glTexCoord2f(0.0, 0.0);
+ glVertex3f(x2, 0.0, z2+0.25);
+ glTexCoord2f(0.25, 0.0);
+ glVertex3f(x2, 0.0, z2-0.25);
+ glTexCoord2f(0.25, 0.5);
+ glVertex3f(x2, 1.0, z2-0.25);
+ glTexCoord2f(0.0, 0.5);
+ glVertex3f(x2, 1.0, z2+0.25);
+ mi->polygon_count++;
+
+ glNormal3f(-1.0, 0.0, 0.0);
+ glTexCoord2f(0.0, 0.0);
+ glVertex3f(x1, 0.0, z1-0.25);
+ glTexCoord2f(0.25, 0.0);
+ glVertex3f(x1, 0.0, z1+0.25);
+ glTexCoord2f(0.25, 0.5);
+ glVertex3f(x1, 1.0, z1+0.25);
+ glTexCoord2f(0.0, 0.5);
+ glVertex3f(x1, 1.0, z1-0.25);
+ mi->polygon_count++;
+
+ glEnd();
+}
+#endif
+
+static void draw_board(ModeInfo *mi, antmazestruct *mp)
+{
+
+ int i, j;
+ double h = 0.5;
+ double stf = 0.0625;
+
+ glBindTexture(GL_TEXTURE_2D, mp->checktexture);
+
+ glBegin(GL_QUADS);
+
+ for(i = 0; i < BOARDSIZE; ++i)
+ for(j = 0; j < BOARDSIZE; ++j) {
+ if(mp->board[mp->currentboard][j][i]) {
+
+/* /\* draw top *\/ */
+/* glNormal3f(0.0, 1.0, 0.0); */
+/* glTexCoord2f(0.0 + stf, 0.0 + stf); */
+/* glVertex3f(i-0.5, h, j+0.5); */
+/* glTexCoord2f(1.0 + stf, 0.0 + stf); */
+/* glVertex3f(i+0.5, h, j+0.5); */
+/* glTexCoord2f(1.0 + stf, 1.0 + stf); */
+/* glVertex3f(i+0.5, h, j-0.5); */
+/* glTexCoord2f(0.0 + stf, 1.0 + stf); */
+/* glVertex3f(i-0.5, h, j-0.5); */
+
+ /* draw top */
+ glNormal3f(0.0, 1.0, 0.0);
+ glTexCoord2f(0.0 + stf, 0.0 + stf);
+ glVertex3f(i-0.5, h, j+0.5);
+ glTexCoord2f(1.0 + stf, 0.0 + stf);
+ glVertex3f(i+0.5, h, j+0.5);
+ glTexCoord2f(1.0 + stf, 1.0 + stf);
+ glVertex3f(i+0.5, h, j-0.5);
+ glTexCoord2f(0.0 + stf, 1.0 + stf);
+ glVertex3f(i-0.5, h, j-0.5);
+ mi->polygon_count++;
+
+ /* draw south face */
+ if(j == 9 || !mp->board[mp->currentboard][j+1][i]) {
+ glNormal3f(0.0, 0.0, 1.0);
+ glTexCoord2f(0.0 + stf, 0.0 + stf);
+ glVertex3f(i-0.5, 0.0, j+0.5);
+ glTexCoord2f(1.0 + stf, 0.0 + stf);
+ glVertex3f(i+0.5, 0.0, j+0.5);
+ glTexCoord2f(1.0 + stf, h + stf);
+ glVertex3f(i+0.5, h, j+0.5);
+ glTexCoord2f(0.0 + stf, h + stf);
+ glVertex3f(i-0.5, h, j+0.5);
+ mi->polygon_count++;
+ }
+
+ /* draw north face */
+ if(j == 0 || !mp->board[mp->currentboard][j-1][i]) {
+ glNormal3f(0.0, 0.0, -1.0);
+ glTexCoord2f(0.0 + stf, 0.0 + stf);
+ glVertex3f(i+0.5, 0.0, j-0.5);
+ glTexCoord2f(1.0 + stf, 0.0 + stf);
+ glVertex3f(i-0.5, 0.0, j-0.5);
+ glTexCoord2f(1.0 + stf, h + stf);
+ glVertex3f(i-0.5, h, j-0.5);
+ glTexCoord2f(0.0 + stf, h + stf);
+ glVertex3f(i+0.5, h, j-0.5);
+ mi->polygon_count++;
+ }
+
+ /* draw east face */
+ if(i == 9 || !mp->board[mp->currentboard][j][i+1]) {
+ glNormal3f(1.0, 0.0, 0.0);
+ glTexCoord2f(0.0 + stf, 0.0 + stf);
+ glVertex3f(i+0.5, 0.0, j+0.5);
+ glTexCoord2f(1.0 + stf, 0.0 + stf);
+ glVertex3f(i+0.5, 0.0, j-0.5);
+ glTexCoord2f(1.0 + stf, h + stf);
+ glVertex3f(i+0.5, h, j-0.5);
+ glTexCoord2f(0.0 + stf, h + stf);
+ glVertex3f(i+0.5, h, j+0.5);
+ mi->polygon_count++;
+ }
+
+ /* draw west face */
+ if(i == 0 || !mp->board[mp->currentboard][j][i-1]) {
+ glNormal3f(-1.0, 0.0, 0.0);
+ glTexCoord2f(0.0 + stf, 0.0 + stf);
+ glVertex3f(i-0.5, 0.0, j-0.5);
+ glTexCoord2f(1.0 + stf, 0.0 + stf);
+ glVertex3f(i-0.5, 0.0, j+0.5);
+ glTexCoord2f(1.0 + stf, h + stf);
+ glVertex3f(i-0.5, h, j+0.5);
+ glTexCoord2f(0.0 + stf, h + stf);
+ glVertex3f(i-0.5, h, j-0.5);
+ mi->polygon_count++;
+ }
+ }
+ else {
+ double tx = 2.0;
+ glNormal3f(0.0, 1.0, 0.0);
+ glTexCoord2f(0.0, 0.0);
+ glVertex3f(i-0.5, 0.0, j+0.5);
+ glTexCoord2f(tx, 0.0);
+ glVertex3f(i+0.5, 0.0, j+0.5);
+ glTexCoord2f(tx, tx);
+ glVertex3f(i+0.5, 0.0, j-0.5);
+ glTexCoord2f(0.0, tx);
+ glVertex3f(i-0.5, 0.0, j-0.5);
+ mi->polygon_count++;
+ }
+ }
+ glEnd();
+
+/* /\* draw elevator *\/ */
+/* glBindTexture(GL_TEXTURE_2D, brushedtexture); */
+
+/* glBegin(GL_QUADS); */
+
+/* glNormal3f(0.0, 1.0, 0.0); */
+
+/* if(pastfirst) { */
+/* /\* source *\/ */
+/* glTexCoord2f(0.0, 0.0); */
+/* glVertex3f(0.5, 0.0, BOARDSIZE - 0.5 + 0.2); */
+/* glTexCoord2f(1.0, 0.0); */
+/* glVertex3f(1.5, 0.0, BOARDSIZE - 0.5 + 0.2); */
+/* glTexCoord2f(1.0, 1.5); */
+/* glVertex3f(1.5, 0.0, BOARDSIZE + 1.0 + 0.2); */
+/* glTexCoord2f(0.0, 1.5); */
+/* glVertex3f(0.5, 0.0, BOARDSIZE + 1.0 + 0.2); */
+/* mi->polygon_count++; */
+/* } */
+
+/* /\* destination *\/ */
+/* glTexCoord2f(0.0, 0.0); */
+/* glVertex3f(BOARDSIZE - 2.5, elevator, -2.0 - 0.2); */
+/* glTexCoord2f(1.0, 0.0); */
+/* glVertex3f(BOARDSIZE - 1.5, elevator, -2.0 - 0.2); */
+/* glTexCoord2f(1.0, 1.5); */
+/* glVertex3f(BOARDSIZE - 1.5, elevator, -0.5 - 0.2); */
+/* glTexCoord2f(0.0, 1.5); */
+/* glVertex3f(BOARDSIZE - 2.5, elevator, -0.5 - 0.2); */
+/* mi->polygon_count++; */
+
+/* glEnd(); */
+
+/* for(i = 0; i < BOARDSIZE; ++i) */
+/* for(j = 0; j < BOARDSIZE; ++j) { */
+/* if(board[j][i]) { */
+
+/* /\* draw brushed boxtop *\/ */
+/* glNormal3f(0.0, 1.0, 0.0); */
+/* glTexCoord2f(0.0 + stf, 0.0 + stf); */
+/* glVertex3f(i-0.5 + stf, h+0.001, j+0.5 - stf); */
+/* glTexCoord2f(1.0 + stf, 0.0 + stf); */
+/* glVertex3f(i+0.5 - stf, h+0.001, j+0.5 - stf); */
+/* glTexCoord2f(1.0 + stf, 1.0 + stf); */
+/* glVertex3f(i+0.5 - stf, h+0.001, j-0.5 + stf); */
+/* glTexCoord2f(0.0 + stf, 1.0 + stf); */
+/* glVertex3f(i-0.5 + stf, h+0.001, j-0.5 + stf); */
+/* mi->polygon_count++; */
+/* } */
+/* } */
+
+/* glEnd(); */
+}
+
+static void build_board(antmazestruct *mp, int b)
+{
+ int i, j;
+
+ for(i = 0; i < BOARDSIZE; ++i)
+ for(j = 0; j < BOARDSIZE; ++j)
+ mp->board[b][i][j] = 1;
+
+/* for(i = 0; i < BOARDSIZE; ++i) { */
+/* board[0][i] = 1; */
+/* board[i][0] = 1; */
+/* board[BOARDSIZE-1][BOARDSIZE-i] = 1; */
+/* board[BOARDSIZE-i][BOARDSIZE-1] = 1; */
+/* } */
+
+/* board[0][BOARDSIZE-2] = 0; */
+/* board[BOARDSIZE-1][1] = 0; */
+
+
+ mp->board[b][BOARDSIZE-1][1] = 0;
+ mp->board[b][0][BOARDSIZE-2] = 0;
+
+ /* build the ant paths */
+ if(mp->currentboard == b) {
+ for(i = 0; i < ANTCOUNT; ++i) {
+ int sx = BOARDSIZE-2;
+ int sy = 1;
+
+ for(j = 0; ; ++j) {
+ mp->board[b][sx][sy] = 0;
+ mp->antpath[i][j][0] = sy - 5.0;
+ mp->antpath[i][j][1] = sx - 5.0;
+
+ if(random()%2) {
+ if(sx > 1)
+ sx -= 1;
+ else if(sy < BOARDSIZE-2)
+ sy += 1;
+ else
+ break;
+ }
+ else {
+ if(sy < BOARDSIZE-2)
+ sy += 1;
+ else if(sx > 1)
+ sx -= 1;
+ else
+ break;
+ }
+ }
+
+ ++j;
+ mp->antpath[i][j][0] = BOARDSIZE-7.0;
+ mp->antpath[i][j][1] = -7.0;
+ mp->antpathlength[i] = j;
+ }
+ }
+
+/* for(i = 0; i < 20; ++i) { */
+/* int x = 1 + random()%(BOARDSIZE-2); */
+/* int y = 1 + random()%(BOARDSIZE-2); */
+/* board[x][y] = 1; */
+/* } */
+}
+
+/* compute nearness */
+static int near(double a[2], double b[2])
+{
+ return fabs(a[0] - b[0]) < 0.5 && fabs(a[1] - b[1]) < 0.5;
+}
+
+static double sign(double d)
+{
+ return d < 0.0 ? -1.0 : 1.0;
+}
+
+static double min(double a, double b)
+{
+ return a < b ? a : b;
+}
+
+/* draw method for ant */
+static Bool draw_ant(ModeInfo *mi, antmazestruct *mp,
+ const float *Material, int mono, int shadow,
+ float ant_step, Bool (*sphere)(float), Bool (*cone)(float))
+{
+
+ float cos1 = cos(mp->ant_step);
+ float cos2 = cos(mp->ant_step + 2 * Pi / 3);
+ float cos3 = cos(mp->ant_step + 4 * Pi / 3);
+ float sin1 = sin(mp->ant_step);
+ float sin2 = sin(mp->ant_step + 2 * Pi / 3);
+ float sin3 = sin(mp->ant_step + 4 * Pi / 3);
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mono ? MaterialGray5 : Material);
+
+/* glEnable(GL_CULL_FACE); */
+
+ glPushMatrix();
+ glScalef(1, 1.3, 1);
+ if(!((*sphere)(0.18)))
+ return False;
+ glScalef(1, 1 / 1.3, 1);
+ glTranslatef(0.00, 0.30, 0.00);
+ if(!((*sphere)(0.2)))
+ return False;
+
+ glTranslatef(-0.05, 0.17, 0.05);
+ glRotatef(-90, 1, 0, 0);
+ glRotatef(-25, 0, 1, 0);
+ if(!((*cone)(0.05)))
+ return False;
+ glTranslatef(0.00, 0.10, 0.00);
+ if(!((*cone)(0.05)))
+ return False;
+ glRotatef(25, 0, 1, 0);
+ glRotatef(90, 1, 0, 0);
+
+ glScalef(1, 1.3, 1);
+ glTranslatef(0.15, -0.65, 0.05);
+ if(!((*sphere)(0.25)))
+ return False;
+ glScalef(1, 1 / 1.3, 1);
+ glPopMatrix();
+
+/* glDisable(GL_CULL_FACE); */
+
+ glDisable(GL_LIGHTING);
+
+ /* ANTENNAS */
+ glBegin(GL_LINES);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, 0.30, 0.00);
+ glColor3fv(MaterialGray);
+ glVertex3f(0.40, 0.70, 0.40);
+ mi->polygon_count++;
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, 0.30, 0.00);
+ glColor3fv(MaterialGray);
+ glVertex3f(0.40, 0.70, -0.40);
+ mi->polygon_count++;
+ glEnd();
+
+ if(!shadow) {
+ glBegin(GL_POINTS);
+ glColor3fv(mono ? MaterialGray6 : MaterialRed);
+ glVertex3f(0.40, 0.70, 0.40);
+ mi->polygon_count++;
+ glVertex3f(0.40, 0.70, -0.40);
+ mi->polygon_count++;
+ glEnd();
+ }
+
+ /* LEFT-FRONT ARM */
+ glBegin(GL_LINE_STRIP);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, 0.05, 0.18);
+ glVertex3f(0.35 + 0.05 * cos1, 0.15, 0.25);
+ mi->polygon_count++;
+ glColor3fv(MaterialGray);
+ glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45);
+ mi->polygon_count++;
+ glEnd();
+
+ /* LEFT-CENTER ARM */
+ glBegin(GL_LINE_STRIP);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, 0.00, 0.18);
+ glVertex3f(0.35 + 0.05 * cos2, 0.00, 0.25);
+ mi->polygon_count++;
+ glColor3fv(MaterialGray);
+ glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45);
+ mi->polygon_count++;
+ glEnd();
+
+ /* LEFT-BACK ARM */
+ glBegin(GL_LINE_STRIP);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, -0.05, 0.18);
+ glVertex3f(0.35 + 0.05 * cos3, -0.15, 0.25);
+ mi->polygon_count++;
+ glColor3fv(MaterialGray);
+ glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45);
+ mi->polygon_count++;
+ glEnd();
+
+ /* RIGHT-FRONT ARM */
+ glBegin(GL_LINE_STRIP);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, 0.05, -0.18);
+ glVertex3f(0.35 - 0.05 * sin1, 0.15, -0.25);
+ mi->polygon_count++;
+ glColor3fv(MaterialGray);
+ glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45);
+ mi->polygon_count++;
+ glEnd();
+
+ /* RIGHT-CENTER ARM */
+ glBegin(GL_LINE_STRIP);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, 0.00, -0.18);
+ glVertex3f(0.35 - 0.05 * sin2, 0.00, -0.25);
+ mi->polygon_count++;
+ glColor3fv(MaterialGray);
+ glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45);
+ mi->polygon_count++;
+ glEnd();
+
+ /* RIGHT-BACK ARM */
+ glBegin(GL_LINE_STRIP);
+ glColor3fv(mono ? MaterialGray5 : Material);
+ glVertex3f(0.00, -0.05, -0.18);
+ glVertex3f(0.35 - 0.05 * sin3, -0.15, -0.25);
+ mi->polygon_count++;
+ glColor3fv(MaterialGray);
+ glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45);
+ mi->polygon_count++;
+ glEnd();
+
+ if(!shadow) {
+ glBegin(GL_POINTS);
+ glColor3fv(mono ? MaterialGray8 : MaterialGray35);
+ glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45);
+ glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45);
+ glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45);
+ glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45);
+ glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45);
+ glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45);
+ mi->polygon_count += 6;
+ glEnd();
+ }
+
+ glEnable(GL_LIGHTING);
+
+ return True;
+}
+
+static Bool draw_antmaze_strip(ModeInfo * mi)
+{
+ antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
+ int i;
+ int mono = MI_IS_MONO(mi);
+
+/* glMatrixMode(GL_MODELVIEW); */
+/* glLoadIdentity(); */
+/* glPushMatrix(); */
+
+ glEnable(GL_LIGHTING);
+/* glDisable(GL_BLEND); */
+ glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
+
+ /* set light */
+/* double l1 = 1.0 - (elevator < 1.0 ? elevator : 2.0 - elevator); */
+/* GLfloat df[4] = {0.8*l1, 0.8*l1, 0.8*l1, 1.0}; */
+/* glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
+/* glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
+
+ /* draw board */
+ if(mp->elevator < 1.0) {
+ glEnable(GL_TEXTURE_2D);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray6);
+ glTranslatef(-(BOARDSIZE-1)/2.0, 0.0, -(BOARDSIZE-1)/2.0);
+ draw_board(mi, mp);
+ glTranslatef(BOARDSIZE/2.0, 0.0, BOARDSIZE/2.0);
+ glDisable(GL_TEXTURE_2D);
+ }
+
+ mp->introduced--;
+
+ glTranslatef(0.0, -0.1, 0.0);
+
+ for(i = 0; i < ANTCOUNT; ++i) {
+
+/* glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
+/* glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
+
+ if(!mp->anton[i]) { continue; }
+
+ /* determine location, move to goal */
+ glPushMatrix();
+ glTranslatef(0.0, 0.01, 0.0);
+ glTranslatef(mp->antposition[i][0], mp->antposition[i][2], mp->antposition[i][1]);
+/* glScalef(1.0, 0.01, 1.0); */
+ glScalef(0.6, 0.01, 0.6);
+ glRotatef(180.0 + mp->antdirection[i]*180.0/PI, 0.0, 1.0, 0.0);
+ glRotatef(90.0, 0.0, 0.0, 1.0);
+ glDisable(GL_LIGHTING);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColor4fv(MaterialGrayB);
+
+ glScalef(mp->antsize[i], mp->antsize[i], mp->antsize[i]);
+
+ /* slow down first ant */
+ if(i == 0 && mp->part[i] == mp->antpathlength[i])
+ draw_ant(mi, mp, MaterialGrayB, mono, 1, mp->first_ant_step, mySphere, myCone);
+ else
+ draw_ant(mi, mp, MaterialGrayB, mono, 1, mp->ant_step, mySphere, myCone);
+
+ glPopMatrix();
+
+ glDisable(GL_BLEND);
+ glEnable(GL_LIGHTING);
+
+ glPushMatrix();
+/* glTranslatef(0.0, 0.18, 0.0); */
+ glTranslatef(0.0, 0.12, 0.0);
+ glTranslatef(mp->antposition[i][0], mp->antposition[i][2], mp->antposition[i][1]);
+ glRotatef(180.0 + mp->antdirection[i]*180.0/PI, 0.0, 1.0, 0.0);
+ glRotatef(90.0, 0.0, 0.0, 1.0);
+ glScalef(0.6, 0.6, 0.6);
+
+ glScalef(mp->antsize[i], mp->antsize[i], mp->antsize[i]);
+
+/* glEnable(GL_TEXTURE_2D); */
+/* glBindTexture(GL_TEXTURE_2D, brushedtexture); */
+
+/* glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed); */
+
+ /* slow down first ant */
+ if(i == 0 && mp->part[i] == mp->antpathlength[i] && mp->elevator > 0.0) {
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
+ draw_ant(mi, mp, antmaterial[i], mono, 1, mp->first_ant_step, mySphere, myCone);
+ }
+ else {
+/* glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
+/* glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, mp->brushedtexture);
+ draw_ant(mi, mp, antmaterial[i], mono, 1, mp->ant_step, mySphereTex, myCone);
+ glDisable(GL_TEXTURE_2D);
+ }
+
+
+/* draw_ant(mi, antmaterial[i], mono, 0, ant_step, mySphereTex, myCone); */
+/* glDisable(GL_TEXTURE_2D); */
+ glPopMatrix();
+ }
+
+/* glPopMatrix(); */
+
+/* /\* now draw overlay *\/ */
+/* glDisable(GL_LIGHTING); */
+/* glDisable(GL_BLEND); */
+
+/* /\* go to ortho mode *\/ */
+/* glMatrixMode(GL_PROJECTION); */
+/* glPushMatrix(); */
+/* glLoadIdentity(); */
+/* glOrtho(-4.0, 4.0, -3.0, 3.0, -100.0, 100.0); */
+
+/* /\* translate to corner *\/ */
+/* glTranslatef(4.0-1.2, 3.0-1.2, 0.0); */
+
+/* glDisable(GL_LIGHTING); */
+/* glEnable(GL_BLEND); */
+
+/* /\* draw the 2d board *\/ */
+/* glBegin(GL_QUADS); */
+/* { */
+/* int i, j; */
+/* double sz = 1.0; */
+/* for(i = 0; i < BOARDSIZE; ++i) */
+/* for(j = 0; j < BOARDSIZE; ++j) { */
+/* int par = board[i][j]; */
+/* glColor4f(par ? 0.4 : 0.6, */
+/* par ? 0.4 : 0.6, */
+/* par ? 0.4 : 0.6, */
+/* 0.5); */
+/* glNormal3f(0.0, 0.0, 1.0); */
+/* glVertex3f((sz*(i+1))/BOARDSIZE, (sz*(j+1))/BOARDSIZE, 0.0); */
+/* glVertex3f((sz*i)/BOARDSIZE, (sz*(j+1))/BOARDSIZE, 0.0); */
+/* glVertex3f((sz*i)/BOARDSIZE, (sz*j)/BOARDSIZE, 0.0); */
+/* glVertex3f((sz*(i+1))/BOARDSIZE, (sz*j)/BOARDSIZE, 0.0); */
+/* mi->polygon_count++; */
+/* } */
+/* } */
+/* glEnd(); */
+
+/* glPopMatrix(); */
+
+
+ /* but the step size is the same! */
+ mp->ant_step += 0.18;
+/* if(ant_step > 2*Pi) { */
+/* ant_step = 0.0; */
+/* } */
+
+ if(mp->ant_step > 5*Pi)
+ mp->started = 1;
+
+ mp->ant_position += 1;
+ return True;
+}
+#undef AntmazeDivisions
+#undef AntmazeTransversals
+
+ENTRYPOINT void reshape_antmaze(ModeInfo * mi, int width, int height)
+{
+ double h = (GLfloat) height / (GLfloat) width;
+ int size = (width / 512) + 1;
+ antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
+
+ glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ gluPerspective(45, 1/h, 1, 25.0);
+
+ glMatrixMode(GL_MODELVIEW);
+/* glLineWidth(3.0); */
+ glLineWidth(size);
+ glPointSize(size);
+}
+
+static void update_ants(antmazestruct *mp)
+{
+ int i;
+ GLfloat df[4];
+ df[0] = df[1] = df[2] = 0.8*mp->fadeout;
+ df[3] = 1.0;
+
+ /* fade out */
+ if(mp->fadeoutspeed < -0.00001) {
+
+ if(mp->fadeout <= 0.0) {
+ /* switch boards: rebuild old board, increment current */
+ mp->currentboard = (mp->currentboard+1)%BOARDCOUNT;
+ build_board(mp, mp->currentboard);
+ mp->fadeoutspeed = 0.02;
+ }
+
+ mp->fadeout += mp->fadeoutspeed;
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, df);
+ }
+
+ /* fade in */
+ if(mp->fadeoutspeed > 0.0001) {
+ mp->fadeout += mp->fadeoutspeed;
+ if(mp->fadeout >= 1.0) {
+ mp->fadeout = 1.0;
+ mp->fadeoutspeed = 0.0;
+ mp->entroducing = 12;
+ }
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, df);
+ }
+
+ for(i = 0; i < ANTCOUNT; ++i) {
+
+ if(!mp->anton[i] && mp->elevator < 1.0) {
+
+ /* turn on ant */
+ if(mp->entroducing > 0 && mp->introduced <= 0 && random()%100 == 0) {
+ mp->anton[i] = 1;
+ mp->part[i] = 0;
+ mp->antsize[i] = 0.0;
+ mp->antposition[i][0] = -4.0;
+ mp->antposition[i][1] = 5.0;
+ mp->antdirection[i] = PI/2.0;
+ mp->bposition[i][0] = 0;
+ mp->bposition[i][1] = 8;
+ mp->introduced = 300;
+ mp->entroducing--;
+ }
+
+ continue;
+ }
+
+ if(mp->part[i] == 0 && mp->antsize[i] < 1.0) {
+ mp->antsize[i] += 0.02;
+ continue;
+ }
+
+ if(mp->part[i] > mp->antpathlength[i] && mp->antsize[i] > 0.0) {
+ mp->antsize[i] -= 0.02;
+ if(mp->antvelocity[i] > 0.0) {
+ mp->antvelocity[i] -= 0.02;
+ }
+ else { mp->antvelocity[i] = 0.0; }
+
+ continue;
+ }
+
+ if(mp->part[i] > mp->antpathlength[i] && mp->antsize[i] <= 0.0) {
+ mp->antvelocity[i] = 0.02;
+
+ /* if(i != 0) { */
+ antmaterial[i] = materials[random()%MATERIALS];
+ /* } */
+
+ mp->antdirection[i] = PI/2.0;
+ mp->bposition[i][0] = 0;
+ mp->bposition[i][1] = 8;
+ mp->part[i] = 0;
+
+ mp->antsize[i] = 0.0;
+
+ mp->anton[i] = 0;
+
+ mp->antposition[i][0] = -4.0;
+ mp->antposition[i][1] = 5.0;
+
+ /* /\* reset camera *\/ */
+ /* if(i == focus) { */
+ /* started = 0; */
+ /* ant_step = 0.0; */
+ /* } */
+
+ /* check for the end */
+ if(mp->entroducing <= 0) {
+ int ao = 0, z = 0;
+ for(z = 0; z < ANTCOUNT; ++z) {
+ if(mp->anton[z]) { ao = 1; break; }
+ }
+
+ if(ao == 0) {
+ mp->fadeoutspeed = -0.02;
+ }
+ }
+
+ }
+
+ /* near goal, bend path towards next step */
+ if(near(mp->antposition[i], mp->antpath[i][mp->part[i]])) {
+
+ ++mp->part[i];
+
+/* /\* special first ant *\/ */
+/* if(i == 0 && part[i] > antpathlength[i]) { */
+/* if(fir) */
+/* first_ant_step = ant_step; */
+
+/* antvelocity[i] = 0.0; */
+/* /\* antposition[i][2] += 0.025; *\/ */
+/* elevator += 0.025; */
+
+/* /\* set light *\/ */
+/* double l1 = 1.0 - (elevator < 1.0 ? elevator : 2.0 - elevator); */
+/* GLfloat df[4] = {0.8*l1, 0.8*l1, 0.8*l1, 1.0}; */
+/* glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
+/* glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
+
+/* /\* draw next board *\/ */
+/* if(elevator > 1.0) { */
+
+/* if(makenew == 1) { */
+/* int re; */
+
+/* /\* switch boards: rebuild old board, increment current *\/ */
+/* currentboard = (currentboard+1)%BOARDCOUNT; */
+/* build_board(currentboard); */
+
+/* for(re = 1; re < ANTCOUNT; ++re) { */
+/* anton[re] = 0; */
+/* antmaterial[re] = materials[random()%MATERIALS]; */
+/* } */
+
+/* makenew = 0; */
+
+/* } */
+
+/* /\* draw the other board *\/ */
+/* glEnable(GL_TEXTURE_2D); */
+/* glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray6); */
+
+/* glPushMatrix(); */
+/* glTranslatef(-(-(BOARDSIZE-3.5)+(BOARDSIZE-1)/2.0), 0.0, */
+/* -(2.4+BOARDSIZE+(BOARDSIZE-1)/2.0)); */
+/* draw_board(mi, mp); */
+/* glPopMatrix(); */
+/* glDisable(GL_TEXTURE_2D); */
+/* } */
+/* /\* reset *\/ */
+/* if(elevator > 2.0) { */
+/* antposition[i][0] = -4.0;/\*-= -(-(BOARDSIZE-3.5)+(BOARDSIZE-1)/2.0);*\//\*= -4.0;*\/ */
+/* antposition[i][1] = 5.5;/\*-(2.4+BOARDSIZE+(BOARDSIZE-1)/2.0);*\/ */
+/* /\* antposition[i][2] = 0.15; *\/ */
+/* antdirection[i] = PI/2.0; */
+/* bposition[i][0] = 0; */
+/* bposition[i][1] = 8; */
+/* part[i] = 0; */
+/* antvelocity[i] = 0.02; */
+/* fir = 0; */
+/* antmaterial[i] = MaterialRed; */
+
+/* makenew = 1; */
+
+/* elevator = 0.0; */
+/* introduced = 200; */
+/* } */
+/* else { */
+/* part[i]--; */
+/* } */
+/* } */
+
+ }
+
+ /* move toward goal, correct ant direction if required */
+ else {
+
+ /* difference */
+ double dx = mp->antpath[i][mp->part[i]][0] - mp->antposition[i][0];
+ double dz = - mp->antpath[i][mp->part[i]][1] + mp->antposition[i][1];
+ double theta, ideal;
+
+ if(dz > EPSILON)
+ theta = atan(dz/dx);
+ else
+ theta = dx > EPSILON ? 0.0 : PI;
+
+ ideal = theta - mp->antdirection[i];
+ if(ideal < -Pi/2.0)
+ ideal += Pi;
+
+ /* compute correction */
+ {
+ double dt = sign(ideal) * min(fabs(ideal), PI/90.0);
+ mp->antdirection[i] += dt;
+ if(mp->antdirection[i] > 2.0*PI)
+ mp->antdirection[i] = 0.0;
+ }
+ }
+
+ mp->antposition[i][0] += mp->antvelocity[i] * cos(mp->antdirection[i]);
+ mp->antposition[i][1] += mp->antvelocity[i] * sin(-mp->antdirection[i]);
+ }
+}
+
+static void pinit(antmazestruct *mp)
+{
+ glClearDepth(1.0);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT0, GL_POSITION, position0);
+ glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT1, GL_POSITION, position1);
+
+ glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
+ glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.001);
+ glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
+
+ glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.05);
+ glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.001);
+ glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.1);
+
+
+/* glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); */
+/* glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); */
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
+ glEnable(GL_NORMALIZE);
+ glFrontFace(GL_CCW);
+ glCullFace(GL_BACK);
+
+ /* antmaze */
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
+
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_DEPTH_TEST);
+ glDisable(GL_TEXTURE_2D);
+
+ /* setup textures */
+ makeCheckImage(mp);
+ makeBrushedImage(mp);
+
+ build_board(mp, 0);
+ build_board(mp, 1);
+
+/* makeCheckImage(); */
+/* glPixelStorei(GL_UNPACK_ALIGNMENT, 1); */
+/* glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, */
+/* checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, checkers); */
+/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); */
+/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); */
+
+/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); */
+/* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); */
+/* glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */
+ glEnable(GL_TEXTURE_2D);
+
+/* glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess); */
+/* glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); */
+}
+
+#define MAX_MAGNIFICATION 10
+#define max(a, b) a < b ? b : a
+#define min(a, b) a < b ? a : b
+
+ENTRYPOINT Bool antmaze_handle_event (ModeInfo *mi, XEvent *event)
+{
+ antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
+
+ if (gltrackball_event_handler (event, mp->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &mp->button_down_p))
+ return True;
+
+ if (event->xany.type == ButtonPress)
+ {
+ switch(event->xbutton.button) {
+
+ case Button3:
+ mp->focus = (mp->focus + 1) % ANTCOUNT;
+ return True;
+
+ case Button4:
+ mp->mag = max(mp->mag-1, 1);
+ return True;
+
+ case Button5:
+ mp->mag = min(mp->mag+1, MAX_MAGNIFICATION);
+ return True;
+ }
+ }
+
+ return False;
+}
+
+ENTRYPOINT void init_antmaze(ModeInfo * mi)
+{
+ double rot_speed = 0.3;
+ int i;
+
+ antmazestruct *mp;
+
+ MI_INIT(mi, antmaze);
+ mp = &antmaze[MI_SCREEN(mi)];
+ mp->step = NRAND(90);
+ mp->ant_position = NRAND(90);
+
+
+ mp->antdirection[0] = PI/2.0;
+ mp->antdirection[1] = PI/2.0;
+ mp->antdirection[2] = 0;
+ mp->antdirection[3] = PI/2.0;
+ mp->antdirection[4] = PI/2.0;
+
+ mp->antposition[0][0] = -4.0;
+ mp->antposition[0][1] = 5.0;
+ mp->antposition[0][1] = 0.15;
+
+ mp->antposition[1][0] = -4.0;
+ mp->antposition[1][1] = 3.0;
+ mp->antposition[1][1] = 0.15;
+
+ mp->antposition[2][0] = -1.0;
+ mp->antposition[2][1] = -2.0;
+ mp->antposition[2][1] = 0.15;
+
+ mp->antposition[3][0] = -3.9;
+ mp->antposition[3][1] = 6.0;
+ mp->antposition[3][1] = 0.15;
+
+ mp->antposition[4][0] = 2.0;
+ mp->antposition[4][1] = -2.0;
+ mp->antposition[4][1] = 0.15;
+
+
+
+ for (i = 0; i < ANTCOUNT; i++) {
+ mp->antvelocity[i] = 0.02;
+ mp->antsize[i] = 1.0;
+ mp->anton[i] = 0;
+ }
+
+ mp->bposition[0][0] = 0;
+ mp->bposition[0][1] = 8;
+
+ mp->bposition[1][0] = 9;
+ mp->bposition[1][1] = 1;
+
+ mp->bposition[2][0] = 1;
+ mp->bposition[2][1] = 1;
+
+ mp->bposition[3][0] = 4;
+ mp->bposition[3][1] = 8;
+
+ mp->bposition[4][0] = 2;
+ mp->bposition[4][1] = 1;
+
+ mp->part[0] = 0;
+ mp->part[1] = 1;
+ mp->part[2] = 5;
+ mp->part[3] = 1;
+ mp->part[4] = 3;
+
+ mp->introduced = 0;
+ mp->entroducing = 12;
+ mp->fadeout = 1.0;
+ mp->mag = 4.0;
+
+ mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
+ mp->trackball = gltrackball_init (False);
+
+ if ((mp->glx_context = init_GL(mi)) != NULL) {
+ reshape_antmaze(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ glDrawBuffer(GL_BACK);
+ pinit(mp);
+ }
+ else
+ MI_CLEARWINDOW(mi);
+}
+
+static void
+device_rotate(ModeInfo *mi)
+{
+#if 0
+ GLfloat rot = current_device_rotation();
+ glRotatef(rot, 0, 0, 1);
+ if ((rot > 45 && rot < 135) ||
+ (rot < -45 && rot > -135))
+ {
+ GLfloat s = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+ glScalef (1/s, s, 1);
+ }
+#endif
+}
+
+
+ENTRYPOINT void draw_antmaze(ModeInfo * mi)
+{
+ double h = (GLfloat) MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+
+ antmazestruct *mp;
+
+ Display *display = MI_DISPLAY(mi);
+ Window window = MI_WINDOW(mi);
+
+ if(!antmaze)
+ return;
+ mp = &antmaze[MI_SCREEN(mi)];
+
+ MI_IS_DRAWN(mi) = True;
+
+ if(!mp->glx_context)
+ return;
+
+ mi->polygon_count = 0;
+ glXMakeCurrent(display, window, *(mp->glx_context));
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /* first panel */
+ glPushMatrix();
+/* h = ((GLfloat) MI_HEIGHT(mi)/2) / (3*(GLfloat)MI_WIDTH(mi)/4); */
+ glViewport(MI_WIDTH(mi)/32, MI_HEIGHT(mi)/8, (9*MI_WIDTH(mi))/16, 3*MI_HEIGHT(mi)/4);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+/* h = (3*MI_HEIGHT(mi)/4) / (3*MI_WIDTH(mi)/4); */
+ gluPerspective(45, 1/h, 1, 25.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ device_rotate(mi);
+
+ glPushMatrix();
+
+ /* follow focused ant */
+ glTranslatef(0.0, 0.0, -mp->mag - 5.0);
+ glRotatef(20.0+5.0*sin(mp->ant_step/40.0), 1.0, 0.0, 0.0);
+/* glTranslatef(0.0, */
+/* started ? -mag : -8.0 + 4.0*fabs(sin(ant_step/10.0)), */
+/* started ? -mag : -8.0 + 4.0*fabs(sin(ant_step/10.0))); */
+
+ gltrackball_rotate(mp->trackball);
+
+ glRotatef(mp->ant_step*0.6, 0.0, 1.0, 0.0);
+
+/* glRotatef(90.0, 0.0, 0.0, 1.0); */
+
+/* glTranslatef(-antposition[0][0]-0.5, 0.0, -antposition[focus][1]); */
+ /*-elevator*/
+
+ /* sync */
+ if(!draw_antmaze_strip(mi)) {
+ MI_ABORT(mi);
+ return;
+ }
+
+ glPopMatrix();
+ glPopMatrix();
+
+ h = (GLfloat) (3*MI_HEIGHT(mi)/8) / (GLfloat) (MI_WIDTH(mi)/2);
+
+ /* draw overhead */
+ glPushMatrix();
+ glViewport((17*MI_WIDTH(mi))/32, MI_HEIGHT(mi)/2, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ device_rotate(mi);
+ gluPerspective(45, 1/h, 1, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+
+ /* twist scene */
+ glTranslatef(0.0, 0.0, -16.0);
+ glRotatef(60.0, 1.0, 0.0, 0.0);
+ glRotatef(-15.0 + mp->ant_step/10.0, 0.0, 1.0, 0.0);
+ gltrackball_rotate(mp->trackball);
+
+ /* sync */
+ if(!draw_antmaze_strip(mi)) {
+ MI_ABORT(mi);
+ return;
+ }
+
+ glPopMatrix();
+
+ /* draw ant display */
+ glPushMatrix();
+ glViewport((5*MI_WIDTH(mi))/8, MI_HEIGHT(mi)/8, (11*MI_WIDTH(mi))/32, 3*MI_HEIGHT(mi)/8);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ device_rotate(mi);
+ gluPerspective(45, 1/h, 1, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+
+ /* twist scene */
+ glTranslatef(0.0, 0.0, -1.6);
+ glRotatef(30.0, 1.0, 0.0, 0.0);
+ glRotatef(mp->ant_step, 0.0, 1.0, 0.0);
+ glRotatef(90.0, 0.0, 0.0, 1.0);
+
+/* /\* draw ant shadow *\/ */
+/* glPushMatrix(); */
+/* glScalef(1.0, 0.01, 1.0); */
+/* glRotatef(90.0, 0.0, 0.0, 1.0); */
+/* glRotatef(90.0, 0.0, 1.0, 0.0); */
+/* glDisable(GL_LIGHTING); */
+/* glColor4fv(MaterialGray6); */
+
+/* /\* slow down first ant *\/ */
+/* draw_ant(MaterialGrayB, 0, 1, first_ant_step, mySphere, myCone); */
+/* glPopMatrix(); */
+
+ /* draw ant body */
+ glEnable(GL_TEXTURE_2D);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
+ glBindTexture(GL_TEXTURE_2D, mp->brushedtexture);
+ draw_ant(mi, mp, MaterialGray35, 0, 1, mp->ant_step/2.0, mySphereTex, myCone2);
+ glDisable(GL_TEXTURE_2D);
+
+ glPopMatrix();
+
+/* /\* draw overlay *\/ */
+/* glPushMatrix(); */
+
+/* /\* go to ortho mode *\/ */
+/* glViewport(MI_WIDTH(mi)/2, MI_HEIGHT(mi)/8, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8); */
+
+/* glMatrixMode(GL_PROJECTION); */
+/* glLoadIdentity(); */
+
+/* glPushMatrix (); */
+/* glOrtho(-4.0, 4.0, -3.0, 3.0, -100.0, 100.0); */
+
+/* glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGrayB); */
+/* glColor4fv(MaterialGrayB); */
+
+/* glDisable(GL_LIGHTING); */
+/* glEnable(GL_BLEND); */
+
+/* glBegin(GL_QUADS); */
+/* glNormal3f(0.0, 0.0, 1.0); */
+/* glVertex3f(4.0, 3.0, 0.0); */
+/* glVertex3f(2.0, 3.0, 0.0); */
+/* glVertex3f(2.0, -3.0, 0.0); */
+/* glVertex3f(4.0, -3.0, 0.0); */
+/* mi->polygon_count++; */
+/* glEnd(); */
+
+/* glEnable(GL_LIGHTING); */
+/* glDisable(GL_BLEND); */
+
+/* glPopMatrix(); */
+/* glPopMatrix(); */
+
+ if (MI_IS_FPS(mi)) {
+ glViewport(0, 0, MI_WIDTH(mi), MI_HEIGHT(mi));
+ do_fps (mi);
+ }
+ glFlush();
+
+ glXSwapBuffers(display, window);
+
+ update_ants(mp);
+
+ mp->step += 0.025;
+}
+
+#ifndef STANDALONE
+ENTRYPOINT void change_antmaze(ModeInfo * mi)
+{
+ antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
+
+ if (!mp->glx_context)
+ return;
+
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
+ pinit();
+}
+#endif /* !STANDALONE */
+
+XSCREENSAVER_MODULE ("AntMaze", antmaze)
+
+#endif