ftp://ftp.sunet.se/pub/vendor/sco/skunkware/osr5/x11/savers/xscreensaver/xscreensaver...
[xscreensaver] / hacks / ant.c
diff --git a/hacks/ant.c b/hacks/ant.c
deleted file mode 100644 (file)
index db76bfd..0000000
+++ /dev/null
@@ -1,1176 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*- */
-/*-
- * ant --- Chris Langton's generalized turing machine ants (also known
- *         as Greg Turk's turmites) whose tape is the screen
- */
-
-#if !defined( lint ) && !defined( SABER )
-static const char sccsid[] = "@(#)ant.c        4.11 98/06/18 xlockmore";
-
-#endif
-
-/*-
- * Copyright (c) 1995 by David Bagley.
- *
- * 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.
- *
- * Revision History:
- * 10-May-97: Compatible with xscreensaver
- * 16-Apr-97: -neighbors 3 and 8 added
- * 01-Jan-97: Updated ant.c to handle more kinds of ants.  Thanks to
- *            J Austin David <Austin.David@tlogic.com>.  Check it out in
- *            java at http://havoc.gtf.gatech.edu/austin  He thought up the
- *            new Ladder ant.
- * 04-Apr-96: -neighbors 6 runtime-time option added for hexagonal ants
- *            (bees), coded from an idea of Jim Propp's in Science News,
- *            Oct 28, 1995 VOL. 148 page 287
- * 20-Sep-95: Memory leak in ant fixed.  Now random colors.
- * 05-Sep-95: Coded from A.K. Dewdney's "Computer Recreations", Scientific
- *            American Magazine" Sep 1989 pp 180-183, Mar 1990 p 121
- *            Also used Ian Stewart's Mathematical Recreations, Scientific
- *            American Jul 1994 pp 104-107
- *            also used demon.c and life.c as a guide.
- */
-
-/*-
-  Species Grid     Number of Neigbors
-  ------- ----     ------------------
-  Ants    Square   4 (or 8)
-  Bees    Hexagon  6
-  Bees    Triangle 3 (or 9, 12)
-
-  Neighbors 6 and neighbors 3 produce the same Turk ants.
-*/
-
-#ifdef STANDALONE
-# define PROGCLASS "Ant"
-# define HACK_INIT init_ant
-# define HACK_DRAW draw_ant
-# define ant_opts xlockmore_opts
-# define DEFAULTS      "*delay:   1000 \n"             \
-                                       "*count:  -3 \n"                \
-                                       "*cycles:  40000 \n"    \
-                                       "*size:   -12 \n"               \
-                                       "*ncolors: 64 \n"               \
-                                       "*neighbors: 0 \n"              \
-                                       "*sharpturn: False \n"
-# include "xlockmore.h"                /* in xscreensaver distribution */
-# include "erase.h"
-#else /* STANDALONE */
-# include "xlock.h"            /* in xlockmore distribution */
-#endif /* STANDALONE */
-
-#include "automata.h"
-
-/*-
- * neighbors of 0 randomizes it between 3, 4 and 6.
- * 8, 9 12 are available also but not recommended.
- */
-
-#ifdef STANDALONE
-static int neighbors;
-#else
-extern int  neighbors;
-#endif /* !STANDALONE */
-
-#define DEF_TRUCHET  "False"
-#define DEF_SHARPTURN  "False"
-#define DEF_NEIGHBORS  "0"
-
-static Bool truchet;
-static Bool sharpturn;
-
-static XrmOptionDescRec opts[] =
-{
-       {"-truchet", ".ant.truchet", XrmoptionNoArg, (caddr_t) "on"},
-       {"+truchet", ".ant.truchet", XrmoptionNoArg, (caddr_t) "off"},
-       {"-sharpturn", ".ant.sharpturn", XrmoptionNoArg, (caddr_t) "on"},
-       {"+sharpturn", ".ant.sharpturn", XrmoptionNoArg, (caddr_t) "off"},
-
-#ifdef STANDALONE
-       {"-neighbors", ".ant.neighbors", XrmoptionSepArg, (caddr_t) 0},
-       {"+neighbors", ".ant.neighbors", XrmoptionSepArg, (caddr_t) 0}
-#endif /* STANDALONE */
-
-};
-static argtype vars[] =
-{
-       {(caddr_t *) & truchet, "truchet", "Truchet", DEF_TRUCHET, t_Bool},
-   {(caddr_t *) & sharpturn, "sharpturn", "SharpTurn", DEF_SHARPTURN, t_Bool},
-#ifdef STANDALONE
-       {(caddr_t *) & neighbors, "neighbors", "Neighbors", DEF_NEIGHBORS, t_Int}
-#endif /* STANDALONE */
-};
-static OptionStruct desc[] =
-{
-       {"-/+truchet", "turn on/off Truchet lines"},
-       {"-/+sharpturn", "turn on/off sharp turns (6 or 12 neighbors only)"}
-};
-
-ModeSpecOpt ant_opts =
-{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
-
-#ifdef USE_MODULES
-ModStruct   ant_description =
-{"ant", "init_ant", "draw_ant", "release_ant",
- "refresh_ant", "init_ant", NULL, &ant_opts,
- 1000, -3, 40000, -12, 64, 1.0, "",
- "Shows Langton's and Turk's generalized ants", 0, NULL};
-
-#endif
-
-#define ANTBITS(n,w,h)\
-  ap->pixmaps[ap->init_bits++]=\
-  XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1)
-
-/* If you change the table you may have to change the following 2 constants */
-#define STATES 2
-#define MINANTS 1
-#define REDRAWSTEP 2000                /* How much tape to draw per cycle */
-#define MINGRIDSIZE 24
-#define MINSIZE 1
-#define MINRANDOMSIZE 5
-#define ANGLES 360
-
-
-typedef struct {
-       unsigned char color;
-       short       direction;
-       unsigned char next;
-} statestruct;
-
-typedef struct {
-       int         col, row;
-       short       direction;
-       unsigned char state;
-} antstruct;
-
-typedef struct {
-       Bool        painted;
-       int         neighbors;
-       int         generation;
-       int         xs, ys;
-       int         xb, yb;
-       int         nrows, ncols;
-       int         width, height;
-       unsigned char ncolors, nstates;
-       int         n;
-       int         redrawing, redrawpos;
-       int         truchet;    /* Only for Turk modes */
-       int         sharpturn;  /* Only for even neighbors > 4 (i.e. 6 and 12) */
-       statestruct machine[NUMSTIPPLES * STATES];
-       unsigned char *tape;
-       unsigned char *truchet_state;
-       antstruct  *ants;
-       int         init_bits;
-       unsigned char colors[NUMSTIPPLES - 1];
-       GC          stippledGC;
-       Pixmap      pixmaps[NUMSTIPPLES - 1];
-       union {
-               XPoint      hexagon[7];         /* Need more than 6 for truchet */
-               XPoint      triangle[2][4];     /* Need more than 3 for truchet */
-       } shape;
-} antfarmstruct;
-
-static char plots[] =
-{3,
-#if 1                          /* Without this... this mode is misnamed... */
- 4,
-#endif
- 6};                           /* Neighborhoods, 8 just makes a mess */
-
-#define NEIGHBORKINDS (long) (sizeof plots / sizeof *plots)
-
-/* Relative ant moves */
-#define FS 0                   /* Step */
-#define TRS 1                  /* Turn right, then step */
-#define THRS 2                 /* Turn hard right, then step */
-#define TBS 3                  /* Turn back, then step */
-#define THLS 4                 /* Turn hard left, then step */
-#define TLS 5                  /* Turn left, then step */
-#define SF 6                   /* Step */
-#define STR 7                  /* Step then turn right */
-#define STHR 8                 /* Step then turn hard right */
-#define STB 9                  /* Step then turn back */
-#define STHL 10                        /* Step then turn hard left */
-#define STL 11                 /* Step then turn left */
-
-static antfarmstruct *antfarms = NULL;
-
-/* LANGTON'S ANT (10) Chaotic after 500, Builder after 10,000 (104p) */
-/* TURK'S 100 ANT Always chaotic?, tested past 150,000,000 */
-/* TURK'S 101 ANT Always chaotic? */
-/* TURK'S 110 ANT Builder at 150 (18p) */
-/* TURK'S 1000 ANT Always chaotic? */
-/* TURK'S 1100 SYMMETRIC ANT  all even run 1's and 0's are symmetric */
-/* other examples 1001, 110011, 110000, 1001101 */
-/* TURK'S 1101 ANT Builder after 250,000 (388p) */
-/* Once saw a chess horse type builder (i.e. non-45 degree builder) */
-
-/* BEE ONLY */
-/* All alternating 10 appear symmetric, no proof (i.e. 10, 1010, etc) */
-/* Even runs of 0's and 1's are also symmetric */
-/* I have seen Hexagonal builders but they are more rare. */
-
-static unsigned char tables[][3 * NUMSTIPPLES * STATES + 2] =
-{
-#if 0
-  /* Here just so you can figure out notation */
-       {                       /* Langton's ant */
-               2, 1,
-               1, TLS, 0, 0, TRS, 0
-       },
-#else
-  /* First 2 numbers are the size (ncolors, nstates) */
-       {                       /* LADDER BUILDER */
-               4, 1,
-               1, STR, 0, 2, STL, 0, 3, TRS, 0, 0, TLS, 0
-       },
-       {                       /* SPIRALING PATTERN */
-               2, 2,
-               1, TLS, 0, 0, FS, 1,
-               1, TRS, 0, 1, TRS, 0
-       },
-       {                       /* SQUARE (HEXAGON) BUILDER */
-               2, 2,
-               1, TLS, 0, 0, FS, 1,
-               0, TRS, 0, 1, TRS, 0
-       },
-#endif
-};
-
-#define NTABLES   (sizeof tables / sizeof tables[0])
-
-static void
-position_of_neighbor(antfarmstruct * ap, int dir, int *pcol, int *prow)
-{
-       int         col = *pcol, row = *prow;
-
-       if (ap->neighbors == 6) {
-               switch (dir) {
-                       case 0:
-                               col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                               break;
-                       case 60:
-                               if (!(row & 1))
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                               row = (!row) ? ap->nrows - 1 : row - 1;
-                               break;
-                       case 120:
-                               if (row & 1)
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                               row = (!row) ? ap->nrows - 1 : row - 1;
-                               break;
-                       case 180:
-                               col = (!col) ? ap->ncols - 1 : col - 1;
-                               break;
-                       case 240:
-                               if (row & 1)
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                               row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                               break;
-                       case 300:
-                               if (!(row & 1))
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                               row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                               break;
-                       default:
-                               (void) fprintf(stderr, "wrong direction %d\n", dir);
-               }
-       } else if (ap->neighbors == 4 || ap->neighbors == 8) {
-               switch (dir) {
-                       case 0:
-                               col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                               break;
-                       case 45:
-                               col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                               row = (!row) ? ap->nrows - 1 : row - 1;
-                               break;
-                       case 90:
-                               row = (!row) ? ap->nrows - 1 : row - 1;
-                               break;
-                       case 135:
-                               col = (!col) ? ap->ncols - 1 : col - 1;
-                               row = (!row) ? ap->nrows - 1 : row - 1;
-                               break;
-                       case 180:
-                               col = (!col) ? ap->ncols - 1 : col - 1;
-                               break;
-                       case 225:
-                               col = (!col) ? ap->ncols - 1 : col - 1;
-                               row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                               break;
-                       case 270:
-                               row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                               break;
-                       case 315:
-                               col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                               row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                               break;
-                       default:
-                               (void) fprintf(stderr, "wrong direction %d\n", dir);
-               }
-       } else {                /* TRI */
-               if ((col + row) % 2) {  /* right */
-                       switch (dir) {
-                               case 0:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       break;
-                               case 30:
-                               case 40:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       row = (!row) ? ap->nrows - 1 : row - 1;
-                                       break;
-                               case 60:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       if (!row)
-                                               row = ap->nrows - 2;
-                                       else if (!(row - 1))
-                                               row = ap->nrows - 1;
-                                       else
-                                               row = row - 2;
-                                       break;
-                               case 80:
-                               case 90:
-                                       if (!row)
-                                               row = ap->nrows - 2;
-                                       else if (!(row - 1))
-                                               row = ap->nrows - 1;
-                                       else
-                                               row = row - 2;
-                                       break;
-                               case 120:
-                                       row = (!row) ? ap->nrows - 1 : row - 1;
-                                       break;
-                               case 150:
-                               case 160:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       row = (!row) ? ap->nrows - 1 : row - 1;
-                                       break;
-                               case 180:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       break;
-                               case 200:
-                               case 210:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                                       break;
-                               case 240:
-                                       row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                                       break;
-                               case 270:
-                               case 280:
-                                       if (row + 1 == ap->nrows)
-                                               row = 1;
-                                       else if (row + 2 == ap->nrows)
-                                               row = 0;
-                                       else
-                                               row = row + 2;
-                                       break;
-                               case 300:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       if (row + 1 == ap->nrows)
-                                               row = 1;
-                                       else if (row + 2 == ap->nrows)
-                                               row = 0;
-                                       else
-                                               row = row + 2;
-                                       break;
-                               case 320:
-                               case 330:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                                       break;
-                               default:
-                                       (void) fprintf(stderr, "wrong direction %d\n", dir);
-                       }
-               } else {        /* left */
-                       switch (dir) {
-                               case 0:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       break;
-                               case 30:
-                               case 40:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                                       break;
-                               case 60:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       if (row + 1 == ap->nrows)
-                                               row = 1;
-                                       else if (row + 2 == ap->nrows)
-                                               row = 0;
-                                       else
-                                               row = row + 2;
-                                       break;
-                               case 80:
-                               case 90:
-                                       if (row + 1 == ap->nrows)
-                                               row = 1;
-                                       else if (row + 2 == ap->nrows)
-                                               row = 0;
-                                       else
-                                               row = row + 2;
-                                       break;
-                               case 120:
-                                       row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                                       break;
-                               case 150:
-                               case 160:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       row = (row + 1 == ap->nrows) ? 0 : row + 1;
-                                       break;
-                               case 180:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       break;
-                               case 200:
-                               case 210:
-                                       col = (!col) ? ap->ncols - 1 : col - 1;
-                                       row = (!row) ? ap->nrows - 1 : row - 1;
-                                       break;
-                               case 240:
-                                       row = (!row) ? ap->nrows - 1 : row - 1;
-                                       break;
-                               case 270:
-                               case 280:
-                                       if (!row)
-                                               row = ap->nrows - 2;
-                                       else if (row == 1)
-                                               row = ap->nrows - 1;
-                                       else
-                                               row = row - 2;
-                                       break;
-                               case 300:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       if (!row)
-                                               row = ap->nrows - 2;
-                                       else if (row == 1)
-                                               row = ap->nrows - 1;
-                                       else
-                                               row = row - 2;
-                                       break;
-                               case 320:
-                               case 330:
-                                       col = (col + 1 == ap->ncols) ? 0 : col + 1;
-                                       row = (!row) ? ap->nrows - 1 : row - 1;
-                                       break;
-                               default:
-                                       (void) fprintf(stderr, "wrong direction %d\n", dir);
-                       }
-               }
-       }
-       *pcol = col;
-       *prow = row;
-}
-
-static void
-fillcell(ModeInfo * mi, GC gc, int col, int row)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-
-       if (ap->neighbors == 6) {
-               int         ccol = 2 * col + !(row & 1), crow = 2 * row;
-
-               ap->shape.hexagon[0].x = ap->xb + ccol * ap->xs;
-               ap->shape.hexagon[0].y = ap->yb + crow * ap->ys;
-               if (ap->xs == 1 && ap->ys == 1)
-                       XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
-                       ap->shape.hexagon[0].x, ap->shape.hexagon[0].y, 1, 1);
-               else
-                       XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
-                           ap->shape.hexagon, 6, Convex, CoordModePrevious);
-       } else if (ap->neighbors == 4 || ap->neighbors == 8) {
-               XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
-               ap->xb + ap->xs * col, ap->yb + ap->ys * row,
-               ap->xs - (ap->xs > 3), ap->ys - (ap->ys > 3));
-       } else {                /* TRI */
-               int         orient = (col + row) % 2;   /* O left 1 right */
-
-               ap->shape.triangle[orient][0].x = ap->xb + col * ap->xs;
-               ap->shape.triangle[orient][0].y = ap->yb + row * ap->ys;
-               if (ap->xs <= 3 || ap->ys <= 3)
-                       XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
-                       ((orient) ? -1 : 1) + ap->shape.triangle[orient][0].x,
-                                      ap->shape.triangle[orient][0].y, 1, 1);
-               else {
-                       if (orient)
-                               ap->shape.triangle[orient][0].x += (ap->xs / 2 - 1);
-                       else
-                               ap->shape.triangle[orient][0].x -= (ap->xs / 2 - 1);
-                       XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
-                                    ap->shape.triangle[orient], 3, Convex, CoordModePrevious);
-               }
-       }
-}
-
-static void
-truchetcell(ModeInfo * mi, int col, int row, int truchetstate)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-
-       if (ap->neighbors == 6) {
-
-               int         ccol = 2 * col + !(row & 1), crow = 2 * row;
-               int         side;
-               int         fudge = 7;  /* fudge because the hexagons are not exact */
-               XPoint      hex, hex2;
-
-               if (ap->sharpturn) {
-                       hex.x = ap->xb + ccol * ap->xs - (int) ((double) ap->xs / 2.0) - 1;
-                       hex.y = ap->yb + crow * ap->ys - (int) ((double) ap->ys / 2.0) - 1;
-                       for (side = 0; side < 6; side++) {
-                               if (side > 0) {
-                                       hex.x += ap->shape.hexagon[side].x;
-                                       hex.y += ap->shape.hexagon[side].y;
-                               }
-                               if (truchetstate == side % 2)
-                                       XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                                hex.x, hex.y, ap->xs, ap->ys,
-                                                ((570 - (side * 60) + fudge) % 360) * 64, (120 - 2 * fudge) * 64);
-                       }
-               } else {
-
-                       /* Very crude approx of Sqrt 3, so it will not cause drawing errors. */
-                       hex.x = ap->xb + ccol * ap->xs - (int) ((double) ap->xs * 1.6 / 2.0);
-                       hex.y = ap->yb + crow * ap->ys - (int) ((double) ap->ys * 1.6 / 2.0);
-                       for (side = 0; side < 6; side++) {
-                               if (side > 0) {
-                                       hex.x += ap->shape.hexagon[side].x;
-                                       hex.y += ap->shape.hexagon[side].y;
-                               }
-                               hex2.x = hex.x + ap->shape.hexagon[side + 1].x / 2;
-                               hex2.y = hex.y + ap->shape.hexagon[side + 1].y / 2;
-                               if (truchetstate == side % 3)
-                                       /* Crude approx of 120 deg, so it will not cause drawing errors. */
-                                       XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                                hex2.x, hex2.y,
-                                                (int) ((double) ap->xs * 1.5), (int) ((double) ap->ys * 1.5),
-                                                ((555 - (side * 60)) % 360) * 64, 90 * 64);
-                       }
-               }
-       } else if (ap->neighbors == 4) {
-               if (truchetstate) {
-                       XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                ap->xb + ap->xs * col - ap->xs / 2+ 1,
-                                ap->yb + ap->ys * row + ap->ys / 2 - 1,
-                                ap->xs - 2, ap->ys - 2,
-                                0 * 64, 90 * 64);
-                       XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                ap->xb + ap->xs * col + ap->xs / 2 - 1,
-                                ap->yb + ap->ys * row - ap->ys / 2 + 1,
-                                ap->xs - 2, ap->ys - 2,
-                                -90 * 64, -90 * 64);
-               } else {
-                       XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                ap->xb + ap->xs * col - ap->xs / 2 + 1,
-                                ap->yb + ap->ys * row - ap->ys / 2 + 1,
-                                ap->xs - 2, ap->ys - 2,
-                                0 * 64, -90 * 64);
-                       XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                ap->xb + ap->xs * col + ap->xs / 2 - 1,
-                                ap->yb + ap->ys * row + ap->ys / 2 - 1,
-                                ap->xs - 2, ap->ys - 2,
-                                90 * 64, 90 * 64);
-               }
-       } else if (ap->neighbors == 3) {
-               int         orient = (col + row) % 2;   /* O left 1 right */
-               int         side, ang;
-               int         fudge = 7;  /* fudge because the triangles are not exact */
-               XPoint      tri;
-
-               tri.x = ap->xb + col * ap->xs;
-               tri.y = ap->yb + row * ap->ys;
-               if (orient) {
-                       tri.x += (ap->xs / 2 - 1);
-               } else {
-                       tri.x -= (ap->xs / 2 - 1);
-               }
-               for (side = 0; side < 3; side++) {
-                       if (side > 0) {
-                               tri.x += ap->shape.triangle[orient][side].x;
-                               tri.y += ap->shape.triangle[orient][side].y;
-                       }
-                       if (truchetstate == side % 3) {
-                               if (orient)
-                                       ang = (510 - side * 120) % 360;         /* Right */
-                               else
-                                       ang = (690 - side * 120) % 360;         /* Left */
-                               XDrawArc(MI_DISPLAY(mi), MI_WINDOW(mi), MI_GC(mi),
-                                 tri.x - ap->xs / 2, tri.y - 3 * ap->ys / 4,
-                                        ap->xs, 3 * ap->ys / 2,
-                                 (ang + fudge) * 64, (60 - 2 * fudge) * 64);
-                       }
-               }
-       }
-}
-
-static void
-drawcell(ModeInfo * mi, int col, int row, unsigned char color)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-       GC          gc;
-
-       if (!color) {
-               XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi));
-               gc = MI_GC(mi);
-       } else if (MI_NPIXELS(mi) > 2) {
-               XSetForeground(MI_DISPLAY(mi), MI_GC(mi),
-                              MI_PIXEL(mi, ap->colors[color - 1]));
-               gc = MI_GC(mi);
-       } else {
-               XGCValues   gcv;
-
-               gcv.stipple = ap->pixmaps[color - 1];
-               gcv.foreground = MI_WHITE_PIXEL(mi);
-               gcv.background = MI_BLACK_PIXEL(mi);
-               XChangeGC(MI_DISPLAY(mi), ap->stippledGC,
-                         GCStipple | GCForeground | GCBackground, &gcv);
-               gc = ap->stippledGC;
-       }
-       fillcell(mi, gc, col, row);
-}
-
-static void
-drawtruchet(ModeInfo * mi, int col, int row,
-           unsigned char color, unsigned char truchetstate)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-
-       if (!color)
-               XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi));
-       else if (MI_NPIXELS(mi) > 2 || color > ap->ncolors / 2)
-               XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_BLACK_PIXEL(mi));
-       else
-               XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi));
-       truchetcell(mi, col, row, truchetstate);
-}
-
-static void
-draw_anant(ModeInfo * mi, int col, int row)
-{
-       XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi));
-       fillcell(mi, MI_GC(mi), col, row);
-#if 0                          /* Can not see eyes */
-       {
-               antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-               Display    *display = MI_DISPLAY(mi);
-               Window      window = MI_WINDOW(mi);
-
-               if (ap->xs > 2 && ap->ys > 2) {         /* Draw Eyes */
-
-                       XSetForeground(display, MI_GC(mi), MI_BLACK_PIXEL(mi));
-                       switch (direction) {
-                               case 0:
-                                       XDrawPoint(display, window, MI_GC(mi),
-                                           ap->xb + ap->xs - 1, ap->yb + 1);
-                                       XDrawPoint(display, window, MI_GC(mi),
-                                                  ap->xb + ap->xs - 1, ap->yb + ap->ys - 2);
-                                       break;
-                               case 180:
-                                       XDrawPoint(display, window, MI_GC(mi), ap->xb, ap->yb + 1);
-                                       XDrawPoint(display, window, MI_GC(mi), ap->xb, ap->yb + ap->ys - 2);
-                                       break;
-                                       if (neighbors == 4) {
-                               case 90:
-                                               XDrawPoint(display, window, MI_GC(mi), ap->xb + 1, ap->yb);
-                                               XDrawPoint(display, window, MI_GC(mi),
-                                               ap->xb + ap->xs - 2, ap->yb);
-                                               break;
-                               case 270:
-                                               XDrawPoint(display, window, MI_GC(mi),
-                                                          ap->xb + 1, ap->yb + ap->ys - 1);
-                                               XDrawPoint(display, window, MI_GC(mi),
-                                                          ap->xb + ap->xs - 2, ap->yb + ap->ys - 1);
-                                               break;
-                                       }       /* else BEE */
-                               default:
-                       }
-               }
-       }
-#endif
-}
-
-#if 0
-static void
-RandomSoup(mi)
-       ModeInfo   *mi;
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-       int         row, col, mrow = 0;
-
-       for (row = 0; row < ap->nrows; ++row) {
-               for (col = 0; col < ap->ncols; ++col) {
-                       ap->old[col + mrow] = (unsigned char) NRAND((int) ap->ncolors);
-                       drawcell(mi, col, row, ap->old[col + mrow]);
-               }
-               mrow += ap->nrows;
-       }
-}
-
-#endif
-
-static short
-fromTableDirection(unsigned char dir, int neighbors)
-{
-       switch (dir) {
-               case FS:
-                       return 0;
-               case TRS:
-                       return (ANGLES / neighbors);
-               case THRS:
-                       return (ANGLES / 2 - ANGLES / neighbors);
-               case TBS:
-                       return (ANGLES / 2);
-               case THLS:
-                       return (ANGLES / 2 + ANGLES / neighbors);
-               case TLS:
-                       return (ANGLES - ANGLES / neighbors);
-               case SF:
-                       return ANGLES;
-               case STR:
-                       return (ANGLES + ANGLES / neighbors);
-               case STHR:
-                       return (3 * ANGLES / 2 - ANGLES / neighbors);
-               case STB:
-                       return (3 * ANGLES / 2);
-               case STHL:
-                       return (3 * ANGLES / 2 + ANGLES / neighbors);
-               case STL:
-                       return (2 * ANGLES - ANGLES / neighbors);
-               default:
-                       (void) fprintf(stderr, "wrong direction %d\n", dir);
-       }
-       return -1;
-}
-
-static void
-getTable(ModeInfo * mi, int i)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-       int         j, total;
-       unsigned char *patptr;
-
-       patptr = &tables[i][0];
-       ap->ncolors = *patptr++;
-       ap->nstates = *patptr++;
-       total = ap->ncolors * ap->nstates;
-       if (MI_IS_VERBOSE(mi))
-               (void) fprintf(stdout,
-                              "ants %d, neighbors %d, table number %d, colors %d, states %d\n",
-                         ap->n, ap->neighbors, i, ap->ncolors, ap->nstates);
-       for (j = 0; j < total; j++) {
-               ap->machine[j].color = *patptr++;
-               if (ap->sharpturn && ap->neighbors > 4 && !(ap->neighbors % 2)) {
-                       int         k = *patptr++;
-
-                       switch (k) {
-                               case TRS:
-                                       k = THRS;
-                                       break;
-                               case THRS:
-                                       k = TRS;
-                                       break;
-                               case THLS:
-                                       k = TLS;
-                                       break;
-                               case TLS:
-                                       k = THLS;
-                                       break;
-                               case STR:
-                                       k = STHR;
-                                       break;
-                               case STHR:
-                                       k = STR;
-                                       break;
-                               case STHL:
-                                       k = STL;
-                                       break;
-                               case STL:
-                                       k = STHL;
-                                       break;
-                               default:
-                                       break;
-                       }
-                       ap->machine[j].direction = fromTableDirection(k, ap->neighbors);
-               } else {
-                       ap->machine[j].direction = fromTableDirection(*patptr++, ap->neighbors);
-               }
-               ap->machine[j].next = *patptr++;
-       }
-       ap->truchet = False;
-}
-
-static void
-getTurk(ModeInfo * mi, int i)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-       int         power2, j, number, total;
-
-       /* To force a number, say <i = 2;> has  i + 2 (or 4) digits in binary */
-       power2 = 1 << (i + 1);
-       /* Dont want numbers which in binary are all 1's. */
-       number = NRAND(power2 - 1) + power2;
-       /* To force a particular number, say <number = 10;> */
-
-       ap->ncolors = i + 2;
-       ap->nstates = 1;
-       total = ap->ncolors * ap->nstates;
-       for (j = 0; j < total; j++) {
-               ap->machine[j].color = (j + 1) % total;
-               if (ap->sharpturn && ap->neighbors > 4 && !(ap->neighbors % 2)) {
-                       ap->machine[j].direction = (power2 & number) ?
-                               fromTableDirection(THRS, ap->neighbors) :
-                               fromTableDirection(THLS, ap->neighbors);
-               } else {
-                       ap->machine[j].direction = (power2 & number) ?
-                               fromTableDirection(TRS, ap->neighbors) :
-                               fromTableDirection(TLS, ap->neighbors);
-               }
-               ap->machine[j].next = 0;
-               power2 >>= 1;
-       }
-       ap->truchet = (ap->truchet && ap->xs > 2 && ap->ys > 2 &&
-          (ap->neighbors == 3 || ap->neighbors == 4 || ap->neighbors == 6));
-       if (MI_IS_VERBOSE(mi))
-               (void) fprintf(stdout,
-                     "ants %d, neighbors %d, Turk's number %d, colors %d\n",
-                              ap->n, ap->neighbors, number, ap->ncolors);
-}
-
-void
-init_ant(ModeInfo * mi)
-{
-       Display    *display = MI_DISPLAY(mi);
-       Window      window = MI_WINDOW(mi);
-       int         size = MI_SIZE(mi);
-       antfarmstruct *ap;
-       int         col, row, dir;
-       long        i;
-
-       /* jwz sez: small sizes look like crap */
-       if (size < 0)
-         size = NRAND(-size)+1;
-       if (size < 5)
-         size += 5;
-
-       if (antfarms == NULL) {
-               if ((antfarms = (antfarmstruct *) calloc(MI_NUM_SCREENS(mi),
-                                           sizeof (antfarmstruct))) == NULL)
-                       return;
-       }
-       ap = &antfarms[MI_SCREEN(mi)];
-       ap->redrawing = 0;
-       if (MI_NPIXELS(mi) <= 2) {
-               if (ap->stippledGC == None) {
-                       XGCValues   gcv;
-
-                       gcv.fill_style = FillOpaqueStippled;
-                       ap->stippledGC = XCreateGC(display, window, GCFillStyle, &gcv);
-               }
-               if (ap->init_bits == 0) {
-                       for (i = 1; i < NUMSTIPPLES; i++)
-                               ANTBITS(stipples[i], STIPPLESIZE, STIPPLESIZE);
-               }
-       }
-       ap->generation = 0;
-       ap->n = MI_COUNT(mi);
-       if (ap->n < -MINANTS) {
-               /* if ap->n is random ... the size can change */
-               if (ap->ants != NULL) {
-                       (void) free((void *) ap->ants);
-                       ap->ants = NULL;
-               }
-               ap->n = NRAND(-ap->n - MINANTS + 1) + MINANTS;
-       } else if (ap->n < MINANTS)
-               ap->n = MINANTS;
-
-       ap->width = MI_WIDTH(mi);
-       ap->height = MI_HEIGHT(mi);
-
-       if (neighbors == 8 || neighbors == 9 || neighbors == 12)
-               ap->neighbors = neighbors;      /* Discourage but not deny use... */
-       else
-               for (i = 0; i < NEIGHBORKINDS; i++) {
-                       if (neighbors == plots[i]) {
-                               ap->neighbors = plots[i];
-                               break;
-                       }
-                       if (i == NEIGHBORKINDS - 1) {
-                               ap->neighbors = plots[NRAND(NEIGHBORKINDS)];
-                               break;
-                       }
-               }
-
-       if (ap->neighbors == 6) {
-               int         nccols, ncrows;
-
-               if (ap->width < 2)
-                       ap->width = 2;
-               if (ap->height < 4)
-                       ap->height = 4;
-               if (size < -MINSIZE) {
-                       ap->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(ap->width, ap->height) /
-                                     MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
-                       if (ap->ys < MINRANDOMSIZE)
-                               ap->ys = MIN(MINRANDOMSIZE,
-                                            MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE));
-               } else if (size < MINSIZE) {
-                       if (!size)
-                               ap->ys = MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE);
-                       else
-                               ap->ys = MINSIZE;
-               } else
-                       ap->ys = MIN(size, MAX(MINSIZE, MIN(ap->width, ap->height) /
-                                              MINGRIDSIZE));
-               ap->xs = ap->ys;
-               nccols = MAX(ap->width / ap->xs - 2, 2);
-               ncrows = MAX(ap->height / ap->ys - 1, 2);
-               ap->ncols = nccols / 2;
-               ap->nrows = 2 * (ncrows / 4);
-               ap->xb = (ap->width - ap->xs * nccols) / 2 + ap->xs / 2;
-               ap->yb = (ap->height - ap->ys * (ncrows / 2) * 2) / 2 + ap->ys;
-               for (i = 0; i < 6; i++) {
-                       ap->shape.hexagon[i].x = (ap->xs - 1) * hexagonUnit[i].x;
-                       ap->shape.hexagon[i].y = ((ap->ys - 1) * hexagonUnit[i].y / 2) * 4 / 3;
-               }
-               /* Avoid array bounds read of hexagonUnit */
-               ap->shape.hexagon[6].x = 0;
-               ap->shape.hexagon[6].y = 0;
-       } else if (ap->neighbors == 4 || ap->neighbors == 8) {
-               if (size < -MINSIZE) {
-                       ap->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(ap->width, ap->height) /
-                                     MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
-                       if (ap->ys < MINRANDOMSIZE)
-                               ap->ys = MIN(MINRANDOMSIZE,
-                                            MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE));
-               } else if (size < MINSIZE) {
-                       if (!size)
-                               ap->ys = MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE);
-                       else
-                               ap->ys = MINSIZE;
-               } else
-                       ap->ys = MIN(size, MAX(MINSIZE, MIN(ap->width, ap->height) /
-                                              MINGRIDSIZE));
-               ap->xs = ap->ys;
-               ap->ncols = MAX(ap->width / ap->xs, 2);
-               ap->nrows = MAX(ap->height / ap->ys, 2);
-               ap->xb = (ap->width - ap->xs * ap->ncols) / 2;
-               ap->yb = (ap->height - ap->ys * ap->nrows) / 2;
-       } else {                /* TRI */
-               int         orient;
-
-               if (ap->width < 2)
-                       ap->width = 2;
-               if (ap->height < 2)
-                       ap->height = 2;
-               if (size < -MINSIZE) {
-                       ap->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(ap->width, ap->height) /
-                                     MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
-                       if (ap->ys < MINRANDOMSIZE)
-                               ap->ys = MIN(MINRANDOMSIZE,
-                                            MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE));
-               } else if (size < MINSIZE) {
-                       if (!size)
-                               ap->ys = MAX(MINSIZE, MIN(ap->width, ap->height) / MINGRIDSIZE);
-                       else
-                               ap->ys = MINSIZE;
-               } else
-                       ap->ys = MIN(size, MAX(MINSIZE, MIN(ap->width, ap->height) /
-                                              MINGRIDSIZE));
-               ap->xs = (int) (1.52 * ap->ys);
-               ap->ncols = (MAX(ap->width / ap->xs - 1, 2) / 2) * 2;
-               ap->nrows = (MAX(ap->height / ap->ys - 1, 2) / 2) * 2;
-               ap->xb = (ap->width - ap->xs * ap->ncols) / 2 + ap->xs / 2;
-               ap->yb = (ap->height - ap->ys * ap->nrows) / 2 + ap->ys;
-               for (orient = 0; orient < 2; orient++) {
-                       for (i = 0; i < 3; i++) {
-                               ap->shape.triangle[orient][i].x =
-                                       (ap->xs - 2) * triangleUnit[orient][i].x;
-                               ap->shape.triangle[orient][i].y =
-                                       (ap->ys - 2) * triangleUnit[orient][i].y;
-                       }
-                       /* Avoid array bounds read of triangleUnit */
-                       ap->shape.triangle[orient][3].x = 0;
-                       ap->shape.triangle[orient][3].y = 0;
-               }
-       }
-
-       XSetLineAttributes(display, MI_GC(mi), 1, LineSolid, CapNotLast, JoinMiter);
-       MI_CLEARWINDOW(mi);
-       ap->painted = False;
-
-       if (MI_IS_FULLRANDOM(mi)) {
-               ap->truchet = (Bool) (LRAND() & 1);
-               ap->sharpturn = (Bool) (LRAND() & 1);
-       } else {
-               ap->truchet = truchet;
-               ap->sharpturn = sharpturn;
-       }
-       /* Exclude odd # of neighbors, stepping forward not defined */
-       if (!NRAND(NUMSTIPPLES) && ((ap->neighbors + 1) % 2)) {
-               getTable(mi, (int) (NRAND(NTABLES)));
-       } else
-               getTurk(mi, (int) (NRAND(NUMSTIPPLES - 1)));
-       if (MI_NPIXELS(mi) > 2)
-               for (i = 0; i < (int) ap->ncolors - 1; i++)
-                       ap->colors[i] = (unsigned char) (NRAND(MI_NPIXELS(mi)) +
-                            i * MI_NPIXELS(mi)) / ((int) (ap->ncolors - 1));
-       if (ap->ants == NULL)
-               ap->ants = (antstruct *) malloc(ap->n * sizeof (antstruct));
-       if (ap->tape != NULL)
-               (void) free((void *) ap->tape);
-       ap->tape = (unsigned char *)
-               calloc(ap->ncols * ap->nrows, sizeof (unsigned char));
-
-       if (ap->truchet_state != NULL)
-               (void) free((void *) ap->truchet_state);
-       ap->truchet_state = (unsigned char *)
-               calloc(ap->ncols * ap->nrows, sizeof (unsigned char));
-
-       col = ap->ncols / 2;
-       row = ap->nrows / 2;
-       dir = NRAND(ap->neighbors) * ANGLES / ap->neighbors;
-       /* Have them all start in the same spot, why not? */
-       for (i = 0; i < ap->n; i++) {
-               ap->ants[i].col = col;
-               ap->ants[i].row = row;
-               ap->ants[i].direction = dir;
-               ap->ants[i].state = 0;
-       }
-       draw_anant(mi, col, row);
-}
-
-void
-draw_ant(ModeInfo * mi)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-       antstruct  *anant;
-       statestruct *status;
-       int         i, state_pos, tape_pos;
-       unsigned char color;
-       short       chg_dir, old_dir;
-
-       MI_IS_DRAWN(mi) = True;
-
-       ap->painted = True;
-       for (i = 0; i < ap->n; i++) {
-               anant = &ap->ants[i];
-               tape_pos = anant->col + anant->row * ap->ncols;
-               color = ap->tape[tape_pos];     /* read tape */
-               state_pos = color + anant->state * ap->ncolors;
-               status = &(ap->machine[state_pos]);
-               drawcell(mi, anant->col, anant->row, status->color);
-               ap->tape[tape_pos] = status->color;     /* write on tape */
-
-               /* Find direction of Bees or Ants. */
-               /* Translate relative direction to actual direction */
-               old_dir = anant->direction;
-               chg_dir = (2 * ANGLES - status->direction) % ANGLES;
-               anant->direction = (chg_dir + old_dir) % ANGLES;
-               if (ap->truchet) {
-                       int         a = 0, b;
-
-                       if (ap->neighbors == 6) {
-                               if (ap->sharpturn) {
-                                       a = (chg_dir / 120 == 2);
-                                       drawtruchet(mi, anant->col, anant->row, status->color, a);
-                               } else {
-                                       a = (old_dir / 60) % 3;
-                                       b = (anant->direction / 60) % 3;
-                                       a = (a + b + 1) % 3;
-                                       drawtruchet(mi, anant->col, anant->row, status->color, a);
-                               }
-                       } else if (ap->neighbors == 4) {
-                               a = old_dir / 180;
-                               b = anant->direction / 180;
-                               a = ((a && !b) || (b && !a));
-                               drawtruchet(mi, anant->col, anant->row, status->color, a);
-                       } else if (ap->neighbors == 3) {
-                               if (chg_dir == 240)
-                                       a = (2 + anant->direction / 120) % 3;
-                               else
-                                       a = (1 + anant->direction / 120) % 3;
-                               drawtruchet(mi, anant->col, anant->row, status->color, a);
-                       }
-                       ap->truchet_state[tape_pos] = a + 1;
-               }
-               anant->state = status->next;
-
-               /* If edge than wrap it */
-               old_dir = ((status->direction < ANGLES) ? anant->direction : old_dir);
-               position_of_neighbor(ap, old_dir, &(anant->col), &(anant->row));
-               draw_anant(mi, anant->col, anant->row);
-       }
-       if (++ap->generation > MI_CYCLES(mi)) {
-#ifdef STANDALONE
-         erase_full_window(MI_DISPLAY(mi), MI_WINDOW(mi));
-#endif
-               init_ant(mi);
-       }
-       if (ap->redrawing) {
-               for (i = 0; i < REDRAWSTEP; i++) {
-                       if (ap->tape[ap->redrawpos] ||
-                        (ap->truchet && ap->truchet_state[ap->redrawpos])) {
-                               drawcell(mi, ap->redrawpos % ap->ncols, ap->redrawpos / ap->ncols,
-                                        ap->tape[ap->redrawpos]);
-                               if (ap->truchet)
-                                       drawtruchet(mi, ap->redrawpos % ap->ncols, ap->redrawpos / ap->ncols,
-                                                   ap->tape[ap->redrawpos],
-                                       ap->truchet_state[ap->redrawpos] - 1);
-                       }
-                       if (++(ap->redrawpos) >= ap->ncols * ap->nrows) {
-                               ap->redrawing = 0;
-                               break;
-                       }
-               }
-       }
-}
-
-void
-release_ant(ModeInfo * mi)
-{
-       if (antfarms != NULL) {
-               int         screen;
-
-               for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
-                       antfarmstruct *ap = &antfarms[screen];
-                       int         shade;
-
-                       if (ap->stippledGC != None) {
-                               XFreeGC(MI_DISPLAY(mi), ap->stippledGC);
-                       }
-                       for (shade = 0; shade < ap->init_bits; shade++)
-                               XFreePixmap(MI_DISPLAY(mi), ap->pixmaps[shade]);
-                       if (ap->tape != NULL)
-                               (void) free((void *) ap->tape);
-                       if (ap->ants != NULL)
-                               (void) free((void *) ap->ants);
-                       if (ap->truchet_state != NULL)
-                               (void) free((void *) ap->truchet_state);
-               }
-               (void) free((void *) antfarms);
-               antfarms = NULL;
-       }
-}
-
-void
-refresh_ant(ModeInfo * mi)
-{
-       antfarmstruct *ap = &antfarms[MI_SCREEN(mi)];
-
-       if (ap->painted) {
-               MI_CLEARWINDOW(mi);
-               ap->redrawing = 1;
-               ap->redrawpos = 0;
-       }
-}