From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / antmaze.c
index 4ce50878ce0e6e0ad7fb7cc7c04287e115b4407b..229257b9576fc7680ab606e862ce8eabf6d8fa01 100644 (file)
  * tennessy@cs.ubc.ca
  */
 
-#if !defined( lint ) && !defined( SABER )
-static const char sccsid[] = "@(#)moebius.c    5.01 2001/03/01 xlockmore";
-#endif
-
-#ifdef VMS
-#include <X11/Intrinsic.h>
+#if 0
+static const char sccsid[] = "@(#)antmaze.c    5.01 2001/03/01 xlockmore";
 #endif
 
 #ifdef STANDALONE
-# define MODE_moebius
-# define PROGCLASS                     "AntMaze2"
-# define HACK_INIT                     init_moebius
-# define HACK_DRAW                     draw_moebius
-# define HACK_RESHAPE          reshape_moebius
-# define HACK_HANDLE_EVENT     moebius_handle_event
-# define EVENT_MASK                    PointerMotionMask
-# define moebius_opts          xlockmore_opts
-# define DEFAULTS                      "*delay:                20000   \n"                     \
-                                                       "*showFPS:      False   \n"                     \
-                                                       "*wireframe:    False   \n"
+# define MODE_antmaze
+# define DEFAULTS      "*delay:                20000   \n"     \
+                       "*showFPS:      False   \n" \
+                       "*fpsSolid:     True    \n"
+
+# define refresh_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 MODE_moebius
+#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 */
 
-#include <GL/glu.h>
+#ifdef MODE_antmaze
+
+
+#include "sphere.h"
+#include "tube.h"
 #include "rotator.h"
 #include "gltrackball.h"
 
-#define DEF_SOLIDMOEBIUS  "False"
+#define DEF_SOLIDANTMAZE  "False"
 #define DEF_NOANTS  "False"
 
-static int  solidmoebius;
+static int  solidantmaze;
 static int  noants;
 
 static XrmOptionDescRec opts[] =
 {
-  {(char *) "-solidmoebius", (char *) ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "on"},
-  {(char *) "+solidmoebius", (char *) ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "off"},
-  {(char *) "-noants", (char *) ".moebius.noants", XrmoptionNoArg, (caddr_t) "on"},
-  {(char *) "+noants", (char *) ".moebius.noants", XrmoptionNoArg, (caddr_t) "off"}
+  {"-solidantmaze", ".antmaze.solidantmaze", XrmoptionNoArg, "on"},
+  {"+solidantmaze", ".antmaze.solidantmaze", XrmoptionNoArg, "off"},
+  {"-noants", ".antmaze.noants", XrmoptionNoArg, "on"},
+  {"+noants", ".antmaze.noants", XrmoptionNoArg, "off"}
 };
 static argtype vars[] =
 {
-  {(caddr_t *) & solidmoebius, (char *) "solidmoebius", (char *) "Solidmoebius", (char *) DEF_SOLIDMOEBIUS, t_Bool},
-  {(caddr_t *) & noants, (char *) "noants", (char *) "Noants", (char *) DEF_NOANTS, t_Bool}
-
+  {&solidantmaze, "solidantmaze", "Solidantmaze", DEF_SOLIDANTMAZE, t_Bool},
+  {&noants, "noants", "Noants", DEF_NOANTS, t_Bool}
 };
+
 static OptionStruct desc[] =
 {
-       {(char *) "-/+solidmoebius", (char *) "select between a SOLID or a NET Moebius Strip"},
-       {(char *) "-/+noants", (char *) "turn on/off walking ants"}
+       {"-/+solidantmaze", "select between a SOLID or a NET Antmaze Strip"},
+       {"-/+noants", "turn on/off walking ants"}
 };
 
-ModeSpecOpt moebius_opts =
+ENTRYPOINT ModeSpecOpt antmaze_opts =
 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
 
 #ifdef USE_MODULES
-ModStruct   moebius_description =
-{"moebius", "init_moebius", "draw_moebius", "release_moebius",
- "draw_moebius", "change_moebius", (char *) NULL, &moebius_opts,
+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};
 
@@ -94,12 +98,25 @@ ModStruct   moebius_description =
 #define Pi                         M_PI
 #endif
 
-#define ObjMoebiusStrip 0
+#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;
@@ -108,37 +125,71 @@ typedef struct {
   rotator    *rot;
   trackball_state *trackball;
   Bool        button_down_p;
-} moebiusstruct;
 
-#include "ants.h"
+  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 GLfloat MaterialRed[] = {0.6, 0.0, 0.0, 1.0};
-static GLfloat MaterialMagenta[] = {0.6, 0.2, 0.5, 1.0};
-static GLfloat MaterialGray8[] = {0.8, 0.8, 0.8, 1.0};
-static GLfloat MaterialGray35[] = {0.30, 0.30, 0.30, 1.0};
-static GLfloat MaterialGray4[] = {0.40, 0.40, 0.40, 1.0};
-static GLfloat MaterialOrange[] = {1.0, 0.69, 0.00, 1.0};
-static GLfloat MaterialGreen[] = {0.1, 0.4, 0.2, 1.0};
+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 */
-GLfloat front_shininess[] = {60.0};
-GLfloat front_specular[] = {0.8, 0.8, 0.8, 1.0};
-GLfloat ambient[] = {0.1, 0.1, 0.1, 1.0};
-GLfloat ambient2[] = {0.0, 0.0, 0.0, 0.0};
-GLfloat diffuse[] = {0.8, 0.8, 0.8, 1.0};
-GLfloat position0[] = {1.0, 5.0, 1.0, 1.0};
-GLfloat position1[] = {-1.0, -5.0, 1.0, 1.0};
-GLfloat lmodel_ambient[] = {0.8, 0.8, 0.8, 1.0};
-GLfloat lmodel_twoside[] = {GL_TRUE};
-GLfloat spotlight_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
-GLfloat spotlight_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
-
-static moebiusstruct *moebius = (moebiusstruct *) NULL;
+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) {
+static Bool mySphere(float radius) 
+{
+#if 0
   GLUquadricObj *quadObj;
 
   if((quadObj = gluNewQuadric()) == 0)
@@ -146,12 +197,20 @@ static Bool mySphere(float radius) {
   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) {
+static Bool mySphere2(float radius) 
+{
   GLUquadricObj *quadObj;
 
   if((quadObj = gluNewQuadric()) == 0)
@@ -162,9 +221,12 @@ static Bool mySphere2(float radius) {
 
   return True;
 }
+#endif
 
 /* textured sphere */
-static Bool mySphereTex(float radius) {
+static Bool mySphereTex(float radius) 
+{
+#if 0
   GLUquadricObj *quadObj;
   
   if((quadObj = gluNewQuadric()) == 0)
@@ -174,12 +236,21 @@ static Bool mySphereTex(float radius) {
   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) {
+static Bool myCone(float radius) 
+{
+#if 0
   GLUquadricObj *quadObj;
   
   if ((quadObj = gluNewQuadric()) == 0)
@@ -187,109 +258,49 @@ static Bool myCone(float radius) {
   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 ANTCOUNT 4
-#define PI 3.14157
-
-static int focus = 0;
-
 #define MATERIALS 4
-static float* antmaterial[ANTCOUNT] = 
+static const float *antmaterial[ANTCOUNT] = 
   {MaterialRed, MaterialGray35, MaterialGray4, MaterialOrange, MaterialGreen};
 
-static float* materials[MATERIALS] = 
+static const float *materials[MATERIALS] = 
   {MaterialRed, MaterialGray35, MaterialGray4, MaterialOrange};
 
-static double antdirection[ANTCOUNT] = {PI/2.0, PI/2.0, 0.0, PI/2.0, PI/2.0};
 
-static double antposition[ANTCOUNT][3] = {{-4.0, 5.0, 0.15},
-                                         {-4.0, 3.0, 0.15},
-                                         {-1.0, -2.0, 0.15},
-                                         {-3.9, 6.0, 0.15}, 
-                                         {2.0, -2.0, 0.15}};
-
-static int anton[ANTCOUNT] = {1, 0, 0, 0};
-
-static double antvelocity[ANTCOUNT] = {0.02,
-                                      0.02,
-                                      0.02,
-                                      0.02};
-
-static double antsize[ANTCOUNT] = {1.0,
-                                  1.0,
-                                  1.0,
-                                  1.0};
-
-#define EPSILON 0.01
-#define BOARDSIZE 10
-
-int bposition[ANTCOUNT][2] = {{0, 8},
-                             {9, 1},
-                             {1, 1},
-                             {4, 8},
-                             {2, 1},};
-
-#define BOARDCOUNT 2
-int currentboard = 0;
-
-int board[BOARDCOUNT][10][10];/*  = {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, */
-/*                  1, 0, 1, 0, 1, 0, 1, 1, 0, 1, */
-/*                  1, 0, 0, 0, 1, 0, 0, 0, 0, 1, */
-/*                  1, 0, 1, 1, 0, 0, 1, 1, 0, 1, */
-/*                  1, 0, 1, 1, 0, 1, 1, 0, 0, 1, */
-/*                  1, 0, 1, 0, 0, 1, 0, 0, 1, 1, */
-/*                  1, 0, 0, 0, 1, 1, 0, 1, 0, 1, */
-/*                  1, 0, 1, 0, 1, 1, 0, 0, 0, 1, */
-/*                  1, 0, 1, 0, 0, 0, 1, 0, 1, 1, */
-/*                  1, 0, 1, 1, 1, 1, 1, 1, 1, 1,}; */
-
-#define PARTS 20
-int part[ANTCOUNT] = {0, 1, 5, 1, 3};
-double antpath[ANTCOUNT][PARTS][2];/*  = {{-4.0, 5.0}, */
-int antpathlength[ANTCOUNT];
-/*                                   {-4.0, 1.0}, */
-/*                                   {-2.0, 1.0}, */
-/*                                   {-2.0, 0.0}, */
-/*                                   {-1.0, 0.0}, */
-/*                                   {-1.0, -2.0}, */
-/*                                   { 0.0, -2.0}, */
-/*                                   { 0.0, -3.0}, */
-/*                                   { 3.0, -3.0}, */
-/*                                   { 3.0, -6.0},}; */
-
-#define checkImageWidth 64
-#define checkImageHeight 64
-GLubyte checkers[checkImageWidth][checkImageHeight][3];
-GLuint checktexture, brushedtexture;
-double elevator = 0.0;
-
-void makeCheckImage(void) {
-  int i, j, r, c, k;
+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)) {
+      if(((((i&0x8)==0)^((j&0x8)))==0)) {
        int c = 102 + random()%32;
-       checkers[i][j][0] = c;
-       checkers[i][j][1] = c;
-       checkers[i][j][2] = c;
+       mp->checkers[i][j][0] = c;
+       mp->checkers[i][j][1] = c;
+       mp->checkers[i][j][2] = c;
       }
       else {
        int c = 153 + random()%32;
-       checkers[i][j][0] = c;/*153;*/
-       checkers[i][j][1] = c;/*c;*//*0;*/
-       checkers[i][j][2] = c;/*c;*//*0;*/
+       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, &checktexture);
-  glBindTexture(GL_TEXTURE_2D, checktexture);
+  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);
@@ -297,12 +308,13 @@ void makeCheckImage(void) {
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, 
               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 
-              &checkers[0][0]);
+              &mp->checkers[0][0]);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 }
 
-void makeBrushedImage(void) {
-  int i, j, r, c, k;
+static void makeBrushedImage(antmazestruct *mp) 
+{
+  int i, j, c;
 
   for(i = 0; i < checkImageWidth; ++i)
     for(j = 0; j < checkImageHeight; ++j) {
@@ -311,9 +323,9 @@ void makeBrushedImage(void) {
 
 /*       c = (i+j)%8==0 || (i+j+5)%8==0 ? 153 : 102; */
 
-      checkers[i][j][0] = c;
-      checkers[i][j][1] = c;
-      checkers[i][j][2] = c;
+      mp->checkers[i][j][0] = c;
+      mp->checkers[i][j][1] = c;
+      mp->checkers[i][j][2] = c;
     }
   
 /*   for (i = 0; i < checkImageWidth; i++) { */
@@ -337,8 +349,8 @@ void makeBrushedImage(void) {
 /*     } */
 /*   } */
 
-  glGenTextures(1, &brushedtexture);
-  glBindTexture(GL_TEXTURE_2D, brushedtexture);
+  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);
@@ -346,11 +358,13 @@ void makeBrushedImage(void) {
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth, 
               checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 
-              &checkers[0][0]);
+              &mp->checkers[0][0]);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 }
 
-void draw_wall(double x1, double z1, double x2, double z2) {
+#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);
@@ -365,6 +379,7 @@ void draw_wall(double x1, double z1, double x2, double z2) {
   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);
@@ -376,6 +391,7 @@ void draw_wall(double x1, double z1, double x2, double z2) {
   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);
@@ -386,6 +402,7 @@ void draw_wall(double x1, double z1, double x2, double z2) {
   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);
@@ -397,6 +414,7 @@ void draw_wall(double x1, double z1, double x2, double z2) {
   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);
@@ -407,25 +425,26 @@ void draw_wall(double x1, double z1, double x2, double z2) {
   glVertex3f(x1, 1.0, z1+0.25);
   glTexCoord2f(0.0, 0.5);
   glVertex3f(x1, 1.0, z1-0.25);
+  mi->polygon_count++;
 
   glEnd();
 }
+#endif
 
-int pastfirst = 0;
-
-void draw_board(void) {
+static void draw_board(ModeInfo *mi, antmazestruct *mp) 
+{
 
   int i, j;
   double h = 0.5;
   double stf = 0.0625;
 
-  glBindTexture(GL_TEXTURE_2D, checktexture);
+  glBindTexture(GL_TEXTURE_2D, mp->checktexture);
 
   glBegin(GL_QUADS);
 
   for(i = 0; i < BOARDSIZE; ++i)
     for(j = 0; j < BOARDSIZE; ++j) {
-      if(board[currentboard][j][i]) {
+      if(mp->board[mp->currentboard][j][i]) {
 
 /*     /\* draw top *\/ */
 /*     glNormal3f(0.0, 1.0, 0.0); */
@@ -448,9 +467,10 @@ void draw_board(void) {
        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 || !board[currentboard][j+1][i]) {
+       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);
@@ -460,10 +480,11 @@ void draw_board(void) {
          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 || !board[currentboard][j-1][i]) {
+       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);
@@ -473,10 +494,11 @@ void draw_board(void) {
          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 || !board[currentboard][j][i+1]) {
+       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);
@@ -486,10 +508,11 @@ void draw_board(void) {
          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 || !board[currentboard][j][i-1]) {
+       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);
@@ -499,6 +522,7 @@ void draw_board(void) {
          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 {
@@ -512,6 +536,7 @@ void draw_board(void) {
        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();
@@ -533,6 +558,7 @@ void draw_board(void) {
 /*       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 *\/ */
@@ -544,6 +570,7 @@ void draw_board(void) {
 /*   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(); */
 
@@ -561,18 +588,20 @@ void draw_board(void) {
 /*     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(); */
 }
 
-void build_board(int b) {
+static void build_board(antmazestruct *mp, int b) 
+{
   int i, j;
 
   for(i = 0; i < BOARDSIZE; ++i)
     for(j = 0; j < BOARDSIZE; ++j)
-      board[b][i][j] = 1;
+      mp->board[b][i][j] = 1;
   
 /*   for(i = 0; i < BOARDSIZE; ++i) { */
 /*     board[0][i] = 1; */
@@ -585,19 +614,19 @@ void build_board(int b) {
 /*   board[BOARDSIZE-1][1] = 0; */
 
 
-  board[b][BOARDSIZE-1][1] = 0;
-  board[b][0][BOARDSIZE-2] = 0;
+  mp->board[b][BOARDSIZE-1][1] = 0;
+  mp->board[b][0][BOARDSIZE-2] = 0;
 
   /* build the ant paths */
-  if(currentboard == b) {
+  if(mp->currentboard == b) {
     for(i = 0; i < ANTCOUNT; ++i) {
       int sx = BOARDSIZE-2;
       int sy = 1;
       
       for(j = 0; ; ++j) {
-       board[b][sx][sy] = 0;
-       antpath[i][j][0] = sy - 5.0;
-       antpath[i][j][1] = sx - 5.0;
+       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)
@@ -618,9 +647,9 @@ void build_board(int b) {
       }
       
       ++j;
-      antpath[i][j][0] = BOARDSIZE-7.0;
-      antpath[i][j][1] = -7.0;
-      antpathlength[i] = j;
+      mp->antpath[i][j][0] = BOARDSIZE-7.0;
+      mp->antpath[i][j][1] = -7.0;
+      mp->antpathlength[i] = j;
     }
   }
 
@@ -632,28 +661,33 @@ void build_board(int b) {
 }
 
 /* compute nearness */
-int near(double a[2], double b[2]) {
+static int near(double a[2], double b[2]) 
+{
   return fabs(a[0] - b[0]) < 0.5 && fabs(a[1] - b[1]) < 0.5;
 }
 
-double sign(double d) {
+static double sign(double d) 
+{
   return d < 0.0 ? -1.0 : 1.0;
 }
 
-double min(double a, double b) {
+static double min(double a, double b) 
+{
   return a < b ? a : b;
 }
 
 /* draw method for ant */
-Bool draw_ant(float *Material, int mono, int shadow,
-             float ant_step, Bool (*sphere)(float), Bool (*cone)(float)) {
+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(ant_step);
-  float cos2 = cos(ant_step + 2 * Pi / 3);
-  float cos3 = cos(ant_step + 4 * Pi / 3);
-  float sin1 = sin(ant_step);
-  float sin2 = sin(ant_step + 2 * Pi / 3);
-  float sin3 = sin(ant_step + 4 * Pi / 3);
+  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);
 
@@ -696,17 +730,21 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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();
   }
 
@@ -715,8 +753,10 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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 */
@@ -724,8 +764,10 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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 */
@@ -733,8 +775,10 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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 */
@@ -742,8 +786,10 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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 */
@@ -751,8 +797,10 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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 */
@@ -760,8 +808,10 @@ Bool draw_ant(float *Material, int mono, int shadow,
   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) {
@@ -773,6 +823,7 @@ Bool draw_ant(float *Material, int mono, int shadow,
     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();
   }
 
@@ -781,16 +832,9 @@ Bool draw_ant(float *Material, int mono, int shadow,
   return True;
 }
 
-double ant_step = 0.0;
-double first_ant_step = 0.0;
-int started = 0;
-int introduced = 300;
-int fir = 0;
-int makenew = 1;
-int entroducing = 12;
-
-static Bool draw_moebius_strip(ModeInfo * mi) {
-  moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
+static Bool draw_antmaze_strip(ModeInfo * mi) 
+{
+  antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
   int i;
   int mono = MI_IS_MONO(mi);
 
@@ -810,16 +854,16 @@ static Bool draw_moebius_strip(ModeInfo * mi) {
 /*   glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
 
   /* draw board */
-  if(elevator < 1.0) {
+  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();
+    draw_board(mi, mp);
     glTranslatef(BOARDSIZE/2.0, 0.0, BOARDSIZE/2.0);
     glDisable(GL_TEXTURE_2D);
   }
 
-  introduced--;
+  mp->introduced--;
 
   glTranslatef(0.0, -0.1, 0.0);
 
@@ -828,28 +872,28 @@ static Bool draw_moebius_strip(ModeInfo * mi) {
 /*     glLightfv(GL_LIGHT0, GL_DIFFUSE, df); */
 /*     glLightfv(GL_LIGHT1, GL_DIFFUSE, df); */
 
-    if(!anton[i]) { continue; }
+    if(!mp->anton[i]) { continue; }
 
     /* determine location, move to goal */
     glPushMatrix();
     glTranslatef(0.0, 0.01, 0.0);
-    glTranslatef(antposition[i][0], antposition[i][2], antposition[i][1]);
+    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 + antdirection[i]*180.0/PI, 0.0, 1.0, 0.0);
+    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(antsize[i], antsize[i], antsize[i]);
+    glScalef(mp->antsize[i], mp->antsize[i], mp->antsize[i]);
 
     /* slow down first ant */
-    if(i == 0 && part[i] == antpathlength[i])
-      draw_ant(MaterialGrayB, mono, 1, first_ant_step, mySphere, myCone);
+    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(MaterialGrayB, mono, 1, ant_step, mySphere, myCone);
+      draw_ant(mi, mp, MaterialGrayB, mono, 1, mp->ant_step, mySphere, myCone);
 
     glPopMatrix();
 
@@ -859,12 +903,12 @@ static Bool draw_moebius_strip(ModeInfo * mi) {
     glPushMatrix();
 /*     glTranslatef(0.0, 0.18, 0.0); */
     glTranslatef(0.0, 0.12, 0.0);
-    glTranslatef(antposition[i][0], antposition[i][2], antposition[i][1]);
-    glRotatef(180.0 + antdirection[i]*180.0/PI, 0.0, 1.0, 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(antsize[i], antsize[i], antsize[i]);
+    glScalef(mp->antsize[i], mp->antsize[i], mp->antsize[i]);
 
 /*     glEnable(GL_TEXTURE_2D); */
 /*     glBindTexture(GL_TEXTURE_2D, brushedtexture); */
@@ -872,23 +916,23 @@ static Bool draw_moebius_strip(ModeInfo * mi) {
 /*     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialRed); */
 
     /* slow down first ant */    
-    if(i == 0 && part[i] == antpathlength[i] && elevator > 0.0) {
+    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(antmaterial[i], mono, 1, first_ant_step, mySphere, myCone);
+      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, brushedtexture);
-      draw_ant(antmaterial[i], mono, 1, ant_step, mySphereTex, myCone);
+      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(antmaterial[i], mono, 0, ant_step, mySphereTex, myCone); */
+/*     draw_ant(mi, antmaterial[i], mono, 0, ant_step, mySphereTex, myCone); */
 /*     glDisable(GL_TEXTURE_2D); */
     glPopMatrix();
   }
@@ -928,6 +972,7 @@ static Bool draw_moebius_strip(ModeInfo * mi) {
 /*     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(); */
@@ -936,30 +981,31 @@ static Bool draw_moebius_strip(ModeInfo * mi) {
 
 
   /* but the step size is the same! */
-  ant_step += 0.18;
+  mp->ant_step += 0.18;
 /*   if(ant_step > 2*Pi) { */
 /*     ant_step = 0.0; */
 /*   } */
 
-  if(ant_step > 5*Pi)
-    started = 1;
+  if(mp->ant_step > 5*Pi)
+    mp->started = 1;
 
   mp->ant_position += 1;
   return True;
 }
-#undef MoebiusDivisions
-#undef MoebiusTransversals
+#undef AntmazeDivisions
+#undef AntmazeTransversals
 
-void reshape_moebius(ModeInfo * mi, int width, int height) {
+ENTRYPOINT void reshape_antmaze(ModeInfo * mi, int width, int height) 
+{
   double h = (GLfloat) height / (GLfloat) width;  
   int size = (width / 512) + 1;
-  moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
+  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, 0.001, 25.0);
+  gluPerspective(45, 1/h, 1, 25.0);
 
   glMatrixMode(GL_MODELVIEW);
 /*   glLineWidth(3.0); */
@@ -967,96 +1013,95 @@ void reshape_moebius(ModeInfo * mi, int width, int height) {
   glPointSize(size);
 }
 
-double fadeout = 1.0;
-double fadeoutspeed = 0.0;
-
-void update_ants(void) {
+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(fadeoutspeed < -0.00001) {
+  if(mp->fadeoutspeed < -0.00001) {
 
-    if(fadeout <= 0.0) {
+    if(mp->fadeout <= 0.0) {
       /* switch boards: rebuild old board, increment current */
-      currentboard = (currentboard+1)%BOARDCOUNT;
-      build_board(currentboard);
-      fadeoutspeed = 0.02;
+      mp->currentboard = (mp->currentboard+1)%BOARDCOUNT;
+      build_board(mp, mp->currentboard);
+      mp->fadeoutspeed = 0.02;
     }
     
-    fadeout += fadeoutspeed;
+    mp->fadeout += mp->fadeoutspeed;
 
-    GLfloat df[4] = {0.8*fadeout, 0.8*fadeout, 0.8*fadeout, 1.0};
     glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
     glLightfv(GL_LIGHT1, GL_DIFFUSE, df);
   }
 
   /* fade in */
-  if(fadeoutspeed > 0.0001) {
-    fadeout += fadeoutspeed;
-    if(fadeout >= 1.0) {
-      fadeout = 1.0;
-      fadeoutspeed = 0.0;
-      entroducing = 12;
+  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;
     }
-    GLfloat df[4] = {0.8*fadeout, 0.8*fadeout, 0.8*fadeout, 1.0};
     glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
     glLightfv(GL_LIGHT1, GL_DIFFUSE, df);    
   }
 
   for(i = 0; i < ANTCOUNT; ++i) {
 
-    if(!anton[i] && elevator < 1.0) {
+    if(!mp->anton[i] && mp->elevator < 1.0) {
 
       /* turn on ant */
-      if(entroducing > 0 && introduced <= 0 && random()%100 == 0) {
-       anton[i] = 1;
-       part[i] = 0;
-       antsize[i] = 0.0;
-       antposition[i][0] = -4.0;
-       antposition[i][1] = 5.0;
-       antdirection[i] = PI/2.0;
-       bposition[i][0] = 0;
-       bposition[i][1] = 8;
-       introduced = 300;
-       entroducing--;
+      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(part[i] == 0 && antsize[i] < 1.0) {
-      antsize[i] += 0.02;
+    if(mp->part[i] == 0 && mp->antsize[i] < 1.0) {
+      mp->antsize[i] += 0.02;
       continue;
     }
 
-    if(part[i] > antpathlength[i] && antsize[i] > 0.0) {
-      antsize[i] -= 0.02;
-      if(antvelocity[i] > 0.0) {
-       antvelocity[i] -= 0.02;
+    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 { antvelocity[i] = 0.0; }
+      else { mp->antvelocity[i] = 0.0; }
 
       continue;
     }
 
-    if(part[i] > antpathlength[i] && antsize[i] <= 0.0) {
-      antvelocity[i] = 0.02;
+    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];
       /*       } */
       
-      antdirection[i] = PI/2.0;
-      bposition[i][0] = 0;
-      bposition[i][1] = 8;
-      part[i] = 0;
+      mp->antdirection[i] = PI/2.0;
+      mp->bposition[i][0] = 0;
+      mp->bposition[i][1] = 8;
+      mp->part[i] = 0;
       
-      antsize[i] = 0.0;
+      mp->antsize[i] = 0.0;
       
-      anton[i] = 0;
+      mp->anton[i] = 0;
       
-      antposition[i][0] = -4.0;
-      antposition[i][1] = 5.0;
+      mp->antposition[i][0] = -4.0;
+      mp->antposition[i][1] = 5.0;
       
       /*       /\* reset camera *\/ */
       /*       if(i == focus) { */
@@ -1065,23 +1110,23 @@ void update_ants(void) {
       /*       } */
       
       /* check for the end */
-      if(entroducing <= 0) {
+      if(mp->entroducing <= 0) {
        int ao = 0, z = 0;
        for(z = 0; z < ANTCOUNT; ++z) {
-         if(anton[z]) { ao = 1; break; }
+         if(mp->anton[z]) { ao = 1; break; }
        }
 
        if(ao == 0) {
-         fadeoutspeed = -0.02;
+         mp->fadeoutspeed = -0.02;
        }
       }
 
     }
     
     /* near goal, bend path towards next step */
-    if(near(antposition[i], antpath[i][part[i]])) {
+    if(near(mp->antposition[i], mp->antpath[i][mp->part[i]])) {
       
-      ++part[i];
+      ++mp->part[i];
 
 /*       /\* special first ant *\/ */
 /*       if(i == 0 && part[i] > antpathlength[i]) { */
@@ -1124,7 +1169,7 @@ void update_ants(void) {
 /*       glPushMatrix(); */
 /*       glTranslatef(-(-(BOARDSIZE-3.5)+(BOARDSIZE-1)/2.0), 0.0,  */
 /*                    -(2.4+BOARDSIZE+(BOARDSIZE-1)/2.0)); */
-/*       draw_board(); */
+/*       draw_board(mi, mp); */
 /*       glPopMatrix(); */
 /*       glDisable(GL_TEXTURE_2D); */
 /*     } */
@@ -1157,8 +1202,8 @@ void update_ants(void) {
     else {
       
       /* difference */
-      double dx = antpath[i][part[i]][0] - antposition[i][0];
-      double dz = - antpath[i][part[i]][1] + antposition[i][1];
+      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)
@@ -1166,27 +1211,27 @@ void update_ants(void) {
       else
        theta = dx > EPSILON ? 0.0 : PI;
       
-      ideal = theta - antdirection[i];
+      ideal = theta - mp->antdirection[i];
       if(ideal < -Pi/2.0)
        ideal += Pi;
 
       /* compute correction */
-      double dt = sign(ideal) * min(fabs(ideal), PI/90.0);
-      antdirection[i] += dt;
-      if(antdirection[i] > 2.0*PI)
-       antdirection[i] = 0.0;
+      {
+        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;
+      }
     }
     
-    antposition[i][0] += antvelocity[i] * cos(antdirection[i]);
-    antposition[i][1] += antvelocity[i] * sin(-antdirection[i]);
+    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(void) {
-  int status;
+static void pinit(antmazestruct *mp) 
+{
   glClearDepth(1.0);
-  glClearColor(0.0, 0.0, 0.0, 1.0);
-  
   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
   glLightfv(GL_LIGHT0, GL_POSITION, position0);
@@ -1212,7 +1257,7 @@ static void pinit(void) {
   glFrontFace(GL_CCW);
   glCullFace(GL_BACK);
   
-  /* moebius */
+  /* antmaze */
   glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
 
@@ -1221,11 +1266,11 @@ static void pinit(void) {
   glDisable(GL_TEXTURE_2D);
 
   /* setup textures */
-  makeCheckImage();
-  makeBrushedImage();
+  makeCheckImage(mp);
+  makeBrushedImage(mp);
 
-  build_board(0);
-  build_board(1);
+  build_board(mp, 0);
+  build_board(mp, 1);
 
 /*   makeCheckImage(); */
 /*   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); */
@@ -1243,116 +1288,160 @@ static void pinit(void) {
 /*   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); */
 }
 
-void release_moebius(ModeInfo * mi) {
-  if(moebius) {
-       free((void *) moebius);
-       moebius = (moebiusstruct *) NULL;
-  }
-  FreeAllGL(mi);
-}
-
-int mag = 4.0;
 #define MAX_MAGNIFICATION 10
 #define max(a, b) a < b ? b : a
 #define min(a, b) a < b ? a : b
 
-Bool moebius_handle_event (ModeInfo *mi, XEvent *event) {
-  moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
-
-  switch(event->xany.type) {
-  case ButtonPress:
+ENTRYPOINT Bool antmaze_handle_event (ModeInfo *mi, XEvent *event) 
+{
+  antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
 
-    switch(event->xbutton.button) {
+  if (gltrackball_event_handler (event, mp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &mp->button_down_p))
+    return True;
 
-    case Button1:
-      mp->button_down_p = True;
-      gltrackball_start(mp->trackball, 
-                       event->xbutton.x, event->xbutton.y,
-                       MI_WIDTH (mi), MI_HEIGHT (mi));
-      break;
+  if (event->xany.type == ButtonPress)
+    {
+      switch(event->xbutton.button) {
 
-    case Button3:
-      focus = (focus + 1) % ANTCOUNT;
-      break;
+      case Button3:
+        mp->focus = (mp->focus + 1) % ANTCOUNT;
+        return True;
       
-    case Button4:
-      mag = max(mag-1, 1);
-      break;
+      case Button4:
+        mp->mag = max(mp->mag-1, 1);
+        return True;
 
-    case Button5:
-      mag = min(mag+1, MAX_MAGNIFICATION);
-      break;
+      case Button5:
+        mp->mag = min(mp->mag+1, MAX_MAGNIFICATION);
+        return True;
+      }
     }
 
-    break;
-    
-  case ButtonRelease:
+  return False;
+}
 
-    switch(event->xbutton.button) {
-    case Button1:
-      mp->button_down_p = False;
-      break;
-    }
+ENTRYPOINT void init_antmaze(ModeInfo * mi) 
+{
+  double rot_speed = 0.3;
+  int i;
 
-    break;
+  antmazestruct *mp;
+  
+  MI_INIT(mi, antmaze, NULL);
+  mp = &antmaze[MI_SCREEN(mi)];
+  mp->step = NRAND(90);
+  mp->ant_position = NRAND(90);
 
-  case MotionNotify:
-    if(mp->button_down_p)
-      gltrackball_track(mp->trackball,
-                       event->xmotion.x, event->xmotion.y,
-                       MI_WIDTH (mi), MI_HEIGHT (mi));
-    break;
-    
-  default:
-    return False;
-  }
 
-  return True;
-}
+  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;
 
-void init_moebius(ModeInfo * mi) {
-  double rot_speed = 0.3;
+  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;
 
-  moebiusstruct *mp;
   
-  if (moebius == NULL) {
-       if ((moebius = (moebiusstruct *) calloc(MI_NUM_SCREENS(mi),
-                                               sizeof (moebiusstruct))) == NULL)
-         return;
+
+  for (i = 0; i < ANTCOUNT; i++) {
+    mp->antvelocity[i] = 0.02;
+    mp->antsize[i] = 1.0;
+    mp->anton[i] = 0;
   }
-  mp = &moebius[MI_SCREEN(mi)];
-  mp->step = NRAND(90);
-  mp->ant_position = NRAND(90);
+
+  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 ();
+  mp->trackball = gltrackball_init (False);
   
   if ((mp->glx_context = init_GL(mi)) != NULL) {
-    reshape_moebius(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+    reshape_antmaze(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
     glDrawBuffer(GL_BACK);
-    pinit();
+    pinit(mp);
   } 
   else
     MI_CLEARWINDOW(mi);
 }
 
-void draw_moebius(ModeInfo * 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);
 
-  moebiusstruct *mp;
+  antmazestruct *mp;
   
   Display    *display = MI_DISPLAY(mi);
   Window      window = MI_WINDOW(mi);
   
-  if(!moebius)
+  if(!antmaze)
        return;
-  mp = &moebius[MI_SCREEN(mi)];
+  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);
@@ -1365,23 +1454,24 @@ void draw_moebius(ModeInfo * mi) {
   glLoadIdentity();
 
 /*   h = (3*MI_HEIGHT(mi)/4) / (3*MI_WIDTH(mi)/4); */
-  gluPerspective(45, 1/h, 0.001, 25.0);
+  gluPerspective(45, 1/h, 1, 25.0);
 
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
+  device_rotate(mi);
 
   glPushMatrix();
 
   /* follow focused ant */
-  glTranslatef(0.0, 0.0, -mag - 5.0);
-  glRotatef(20.0+5.0*sin(ant_step/40.0), 1.0, 0.0, 0.0);
+  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(ant_step*0.6, 0.0, 1.0, 0.0);
+  glRotatef(mp->ant_step*0.6, 0.0, 1.0, 0.0);
 
 /*   glRotatef(90.0, 0.0, 0.0, 1.0); */
 
@@ -1389,8 +1479,8 @@ void draw_moebius(ModeInfo * mi) {
   /*-elevator*/
 
   /* sync */
-  if(!draw_moebius_strip(mi)) {
-    release_moebius(mi);
+  if(!draw_antmaze_strip(mi)) {
+    MI_ABORT(mi);
     return;
   }
 
@@ -1404,18 +1494,19 @@ void draw_moebius(ModeInfo * mi) {
   glViewport((17*MI_WIDTH(mi))/32, MI_HEIGHT(mi)/2, MI_WIDTH(mi)/2, 3*MI_HEIGHT(mi)/8);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
-  gluPerspective(45, 1/h, 0.001, 25.0);
+  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 + ant_step/10.0, 0.0, 1.0, 0.0);
+  glRotatef(-15.0 + mp->ant_step/10.0, 0.0, 1.0, 0.0);
   gltrackball_rotate(mp->trackball);
 
   /* sync */
-  if(!draw_moebius_strip(mi)) {
-    release_moebius(mi);
+  if(!draw_antmaze_strip(mi)) {
+    MI_ABORT(mi);
     return;
   }
 
@@ -1426,13 +1517,14 @@ void draw_moebius(ModeInfo * mi) {
   glViewport((5*MI_WIDTH(mi))/8, MI_HEIGHT(mi)/8, (11*MI_WIDTH(mi))/32, 3*MI_HEIGHT(mi)/8);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
-  gluPerspective(45, 1/h, 0.001, 25.0);
+  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(ant_step, 0.0, 1.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 *\/ */
@@ -1451,8 +1543,8 @@ void draw_moebius(ModeInfo * mi) {
   glEnable(GL_TEXTURE_2D);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
   glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
-  glBindTexture(GL_TEXTURE_2D, brushedtexture);
-  draw_ant(MaterialGray35, 0, 1, ant_step/2.0, mySphereTex, myCone2);
+  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();
@@ -1481,6 +1573,7 @@ void draw_moebius(ModeInfo * mi) {
 /*   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); */
@@ -1489,18 +1582,23 @@ void draw_moebius(ModeInfo * mi) {
 /*   glPopMatrix(); */
 /*   glPopMatrix(); */
   
-  if (MI_IS_FPS(mi)) do_fps (mi);
+  if (MI_IS_FPS(mi)) {
+    glViewport(0, 0, MI_WIDTH(mi), MI_HEIGHT(mi));
+    do_fps (mi);
+  }
   glFlush();
   
   glXSwapBuffers(display, window);
   
-  update_ants();
+  update_ants(mp);
 
   mp->step += 0.025;
 }
 
-void change_moebius(ModeInfo * mi) {
-  moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
+#ifndef STANDALONE
+ENTRYPOINT void change_antmaze(ModeInfo * mi) 
+{
+  antmazestruct *mp = &antmaze[MI_SCREEN(mi)];
   
   if (!mp->glx_context)
        return;
@@ -1508,5 +1606,8 @@ void change_moebius(ModeInfo * mi) {
   glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
   pinit();
 }
+#endif /* !STANDALONE */
+
+XSCREENSAVER_MODULE ("AntMaze", antmaze)
 
 #endif