/* -*- Mode: C; tab-width: 4 -*- */
/* loop --- Chris Langton's self-producing loops */
-#if !defined( lint ) && !defined( SABER )
-static const char sccsid[] = "@(#)loop.c 4.13 98/10/18 xlockmore";
-
+#if 0
+static const char sccsid[] = "@(#)loop.c 5.01 2000/03/15 xlockmore";
#endif
/*-
* other special, indirect and consequential damages.
*
* Revision History:
- * 18-Oct-98: Started creating a hexagon version, probably will not work
- * for a while since some work has to go into getting not
- * only the program to handle the hexagonal data but the loop
- * has to be "programmed" as well. I suspect it should be easier
- * than the original since the loop will have six sides to
- * store its genes (data).
- * 10-May-97: Compatible with xscreensaver
- * 15-Nov-95: Coded from Chris Langton's Self-Reproduction in Cellular
- * Automata Physica 10D 135-144 1984
- * also used wire.c as a guide.
+ * 15-Mar-2001: Added some flaws, random blue wall spots, to liven it up.
+ * This mod seems to expose a bug where hexagons are erased
+ * for no apparent reason.
+ * 01-Nov-2000: Allocation checks
+ * 16-Jun-2000: Fully coded the hexagonal rules. (Rules that end up in
+ * state zero were not bothered with since a calloc was used
+ * to set non-explicit rules to zero. This allows the
+ * compile-time option RAND_RULES to work here (at least to
+ * generation 540).)
+ * Also added compile-time option DELAYDEBUGLOOP for debugging
+ * life form. This also turns off the random initial direction
+ * of the loop. Set DELAYDEBUGLOOP to be 10 and use with
+ * something like this:
+ * xlock -mode loop -neighbors 6 -size 5 -delay 1 -count 540 -nolock
+ * 18-Oct-1998: Started creating a hexagon version.
+ * It proved not that difficult because I used Langton's Loop
+ * as a guide, hexagons have more neighbors so there is more
+ * freedom to program, and the loop will has six sides to
+ * store its genes (data).
+ * (Soon after this a triangular version with neighbors = 6
+ * was attempted but was unsuccessful).
+ * 10-May-1997: Compatible with xscreensaver
+ * 15-Nov-1995: Coded from Chris Langton's Self-Reproduction in Cellular
+ * Automata Physica 10D 135-144 1984, also used wire.c as a
+ * guide.
*/
/*-
- Grid Number of Neigbors
+ Grid Number of Neighbors
---- ------------------
Square 4
Hexagon 6 (currently in development)
machine is not contained in the loop. This is a simplification of
von Neumann and Codd's self-producing Turing machine.
The data spinning around could be viewed as both its DNA and its internal
- clock.
+ clock. The program can be initalized to have the loop spin both ways...
+ but only one way around will work for a given rule. An open question (at
+ least to me): Is handedness a requirement for (artificial) life? Here
+ there is handedness at both the initial condition and the transition rule.
*/
+#ifndef HAVE_COCOA
+# define DO_STIPPLE
+#endif
+
#ifdef STANDALONE
-# define PROGCLASS "loop"
-# define HACK_INIT init_loop
-# define HACK_DRAW draw_loop
-# define loop_opts xlockmore_opts
-# define DEFAULTS "*delay: 100000 \n" \
- "*cycles: 1600 \n" \
- "*size: -12 \n" \
- "*ncolors: 15 \n" \
- "*neighbors: 0 \n"
-# define SMOOTH_COLORS
+# define MODE_loop
+# define DEFAULTS "*delay: 100000 \n" \
+ "*count: -5 \n" \
+ "*cycles: 1600 \n" \
+ "*size: -12 \n" \
+ "*ncolors: 15 \n" \
+ "*fpsSolid: true \n" \
+
+# define UNIFORM_COLORS
+# define reshape_loop 0
+# define loop_handle_event 0
# include "xlockmore.h" /* in xscreensaver distribution */
#else /* STANDALONE */
# include "xlock.h" /* in xlockmore distribution */
#endif /* STANDALONE */
-
#include "automata.h"
+#ifdef MODE_loop
+
/*-
* neighbors of 0 randomizes between 4 and 6.
*/
-#ifdef STANDALONE
-static int neighbors;
-#else
-extern int neighbors;
-#endif /* !STANDALONE */
+#define DEF_NEIGHBORS "0" /* choose random value */
+
+static int neighbors;
+
+static XrmOptionDescRec opts[] =
+{
+ {"-neighbors", ".loop.neighbors", XrmoptionSepArg, 0}
+};
+
+static argtype vars[] =
+{
+ {&neighbors, "neighbors", "Neighbors", DEF_NEIGHBORS, t_Int}
+};
+
+static OptionStruct desc[] =
+{
+ {"-neighbors num", "squares 4 or hexagons 6"}
+};
+
+ENTRYPOINT ModeSpecOpt loop_opts =
+{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
-ModeSpecOpt loop_opts =
-{0, NULL, 0, NULL, NULL};
#ifdef USE_MODULES
ModStruct loop_description =
{"loop", "init_loop", "draw_loop", "release_loop",
- "refresh_loop", "init_loop", NULL, &loop_opts,
- 100000, 1, 1600, -12, 64, 1.0, "",
+ "refresh_loop", "init_loop", (char *) NULL, &loop_opts,
+ 100000, 5, 1600, -12, 64, 1.0, "",
"Shows Langton's self-producing loops", 0, NULL};
#endif
#define LOOPBITS(n,w,h)\
- lp->pixmaps[lp->init_bits++]=\
- XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1)
+ if ((lp->pixmaps[lp->init_bits]=\
+ XCreatePixmapFromBitmapData(display,window,(char *)n,w,h,1,0,1))==None){\
+ free_loop(display,lp); return;} else {lp->init_bits++;}
static int local_neighbors = 0;
-static int neighbor_kind = 0;
+
+#if 0
+/* Used to fast forward to troubled generations, mainly used for debugging.
+ -delay 1 -count 170 -neighbors 6 # divisions starts
+ 540 first cell collision
+ 1111 mutant being born from 2 parents
+ 1156 mutant born
+ */
+#define DELAYDEBUGLOOP 10
+#endif
#define COLORS 8
#define REALCOLORS (COLORS-2)
#define REDRAWSTEP 2000 /* How many cells to draw per cycle */
#define ADAM_SIZE 8 /* MIN 5 */
#if 1
-# define ADAM_LOOPX (ADAM_SIZE+2)
-# define ADAM_LOOPY (ADAM_SIZE+2)
+#define ADAM_LOOPX (ADAM_SIZE+2)
+#define ADAM_LOOPY (ADAM_SIZE+2)
#else
-# define ADAM_LOOPX 16
-# define ADAM_LOOPY 10
+#define ADAM_LOOPX 16
+#define ADAM_LOOPY 10
#endif
#define MINGRIDSIZE (3*ADAM_LOOPX)
+#if 0
/* TRIA stuff was an attempt to make a triangular lifeform on a
- hex grid but I got bored. You probably need an additional 7th
- state for a coherent step by step process of separation and
+ hexagonal grid but I got bored. You may need an additional 7th
+ state for a coherent step by step process of cell separation and
initial stem development.
*/
-/* #define TRIA 1 */
+#define TRIA 1
+#endif
#ifdef TRIA
-# define HEX_ADAM_SIZE 3 /* MIN 3 */
+#define HEX_ADAM_SIZE 3 /* MIN 3 */
#else
-# define HEX_ADAM_SIZE 5 /* MIN 3 */
+#define HEX_ADAM_SIZE 5 /* MIN 3 */
#endif
#if 1
-# define HEX_ADAM_LOOPX (2*HEX_ADAM_SIZE+1)
-# define HEX_ADAM_LOOPY (2*HEX_ADAM_SIZE+1)
+#define HEX_ADAM_LOOPX (2*HEX_ADAM_SIZE+1)
+#define HEX_ADAM_LOOPY (2*HEX_ADAM_SIZE+1)
#else
-# define HEX_ADAM_LOOPX 3
-# define HEX_ADAM_LOOPY 7
+#define HEX_ADAM_LOOPX 3
+#define HEX_ADAM_LOOPY 7
#endif
#define HEX_MINGRIDSIZE (6*HEX_ADAM_LOOPX)
-#define MINSIZE 5 /* jwz -- really tiny cells don't look good */
+#define MINSIZE ((MI_NPIXELS(mi)>=COLORS)?1:(2+(local_neighbors==6)))
#define NEIGHBORKINDS 2
#define ANGLES 360
#define MAXNEIGHBORS 6
int mincol, minrow, maxcol, maxrow;
int width, height;
int redrawing, redrawpos;
+ Bool dead, clockwise;
unsigned char *newcells, *oldcells;
int ncells[COLORS];
CellList *cellList[COLORS];
} shape;
} loopstruct;
-static loopstruct *loops = NULL;
+static loopstruct *loops = (loopstruct *) NULL;
#define TRANSITION(TT,V) V=TT&7;TT>>=3
+#define FINALTRANSITION(TT,V) V=TT&7
#define TABLE(R,T,L,B) (table[((B)<<9)|((L)<<6)|((T)<<3)|(R)])
#define HEX_TABLE(R,T,t,l,b,B) (table[((B)<<15)|((b)<<12)|((l)<<9)|((t)<<6)|((T)<<3)|(R)])
-#ifdef RAND_RULES /* Hack, see below */
+
+#if 0
+/* Instead of setting "unused" state rules to zero it randomizes them.
+ These rules take over when something unexpected happens... like when a
+ cell hits a wall (the end of the screen).
+ */
+#define RAND_RULES
+#endif
+
+#ifdef RAND_RULES
#define TABLE_IN(C,R,T,L,B,I) (TABLE(R,T,L,B)&=~(7<<((C)*3)));\
(TABLE(R,T,L,B)|=((I)<<((C)*3)))
#define HEX_TABLE_IN(C,R,T,t,l,b,B,I) (HEX_TABLE(R,T,t,l,b,B)&=~(7<<((C)*3)));\
#define TABLE_OUT(C,R,T,L,B) ((TABLE(R,T,L,B)>>((C)*3))&7)
#define HEX_TABLE_OUT(C,R,T,t,l,b,B) ((HEX_TABLE(R,T,t,l,b,B)>>((C)*3))&7)
-static unsigned int *table = NULL; /* 8*8*8*8 = 2^12 = 2^3^4 = 4K */
- /* 8*8*8*8*8*8 = too big? */
+static unsigned int *table = (unsigned int *) NULL;
+ /* square: 8*8*8*8 = 2^12 = 2^3^4 = 4096 */
+ /* hexagon: 8*8*8*8*8*8 = 2^18 = 2^3^6 = 262144 = too big? */
static char plots[NEIGHBORKINDS] =
{
020102022, 020202112,
000000012, 000000122, 000000212,
- 010002121,
+ 010002121,
020001122, 020002112, 020011122,
020040422,
040002022,
-
+
010224224, 010222424, 010202424,
020142022, 020202412,
020011722, 020112072, 020172072, 020142072,
000210225, 000022015, 000022522,
- 011225521,
+ 011225521,
020120525, 020020152, 020005122, 020214255, 020021152,
020255242,
050215222, 050225121,
001224251,
010022152, 010251221, 010522121, 011212151, 011221251,
011215221,
- 020000220, 020002152, 020020220, 020021020, 020022152,
+ 020000220, 020002152, 020020220, 020022152,
020021422, 020022152, 020022522, 020025425, 020050422,
020051022, 020051122, 020211122, 020211222, 020215222,
020245122,
020021552,
012252277,
050002521,
- 020005725,
+ 020005725,
050011022,
000000155,
020521122,
020025022,
020025522,
- 020020522,
+ 020020522,
020202222,
020212222,
020212122,
020027222,
020024222,
- 020020222,
020212722,
020212422,
020202122,
020212052,
020205052,
+ 070221250,
+
+ 000000050, 000005220, 000002270, 070252220,
+ 000000450, 000007220,
+ 000220220, 000202220, 000022020, 000020220,
+
+ 000222040,
+ 000220440,
+ 000022040,
+ 000040220,
+
+ 000252220,
+ 050221120, 010221520,
+ 002222220,
+
+ 000070220, 000220720,
+ 000020520, 000070250, 000222070, 000027020,
+ 000022070, 000202270, 000024020, 000220420,
+ 000220270, 000220240, 000072020, 000042020,
+ 000002020, 000002070, 000020270, 000020250,
+ 000270270, 000007020, 000040270,
+
+ /* Collision starts (gen 540), not sure to have rules to save it
+ or depend on calloc to intialize remaining rules to 0 so that
+ the mutant will be born
+ */
+ 000050220,
#endif
};
if (local_neighbors == 6) {
switch (dir) {
case 0:
- col = col + 1;
+ col++;
break;
case 60:
- if (row & 1)
- col = col + 1;
- row = row - 1;
+ col += (row & 1);
+ row--;
break;
case 120:
- if (!(row & 1))
- col = col - 1;
- row = row - 1;
+ col -= !(row & 1);
+ row--;
break;
case 180:
- col = col - 1;
+ col--;
break;
case 240:
- if (!(row & 1))
- col = col - 1;
- row = row + 1;
+ col -= !(row & 1);
+ row++;
break;
case 300:
- if (row & 1)
- col = col + 1;
- row = row + 1;
+ col += (row & 1);
+ row++;
break;
default:
(void) fprintf(stderr, "wrong direction %d\n", dir);
} else {
switch (dir) {
case 0:
- col = col + 1;
+ col++;
break;
case 90:
- row = row - 1;
+ row--;
break;
case 180:
- col = col - 1;
+ col--;
break;
case 270:
- row = row + 1;
+ row++;
break;
default:
(void) fprintf(stderr, "wrong direction %d\n", dir);
lp->shape.hexagon[0].x = lp->xb + ccol * lp->xs;
lp->shape.hexagon[0].y = lp->yb + crow * lp->ys;
if (lp->xs == 1 && lp->ys == 1)
- XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
- lp->shape.hexagon[0].x, lp->shape.hexagon[0].y, 1, 1);
+ XDrawPoint(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
+ lp->shape.hexagon[0].x, lp->shape.hexagon[0].y);
else
XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
lp->shape.hexagon, 6, Convex, CoordModePrevious);
gc = MI_GC(mi);
XSetForeground(MI_DISPLAY(mi), gc, lp->colors[state]);
} else {
+#ifdef DO_STIPPLE
gcv.stipple = lp->pixmaps[state];
+#endif /* DO_STIPPLE */
gcv.foreground = MI_WHITE_PIXEL(mi);
gcv.background = MI_BLACK_PIXEL(mi);
XChangeGC(MI_DISPLAY(mi), lp->stippledGC,
- GCStipple | GCForeground | GCBackground, &gcv);
+#ifdef DO_STIPPLE
+ GCStipple |
+#endif /* DO_STIPPLE */
+ GCForeground | GCBackground, &gcv);
gc = lp->stippledGC;
}
fillcell(mi, gc, col, row);
}
-static void
-addtolist(ModeInfo * mi, int col, int row, unsigned char state)
-{
- loopstruct *lp = &loops[MI_SCREEN(mi)];
- CellList *current = lp->cellList[state];
-
- lp->cellList[state] = NULL;
- if ((lp->cellList[state] = (CellList *) malloc(sizeof (CellList))) == NULL) {
- lp->cellList[state] = current;
- return;
- }
- lp->cellList[state]->pt.x = col;
- lp->cellList[state]->pt.y = row;
- lp->cellList[state]->next = current;
- lp->ncells[state]++;
-}
-
#ifdef DEBUG
static void
print_state(ModeInfo * mi, int state)
}
static void
+free_list(loopstruct * lp)
+{
+ int state;
+
+ for (state = 0; state < COLORS; state++)
+ free_state(lp, state);
+}
+
+static void
+free_loop(Display *display, loopstruct * lp)
+{
+ int shade;
+
+ for (shade = 0; shade < lp->init_bits; shade++)
+ if (lp->pixmaps[shade] != None) {
+ XFreePixmap(display, lp->pixmaps[shade]);
+ lp->pixmaps[shade] = None;
+ }
+ if (lp->stippledGC != None) {
+ XFreeGC(display, lp->stippledGC);
+ lp->stippledGC = None;
+ }
+ if (lp->oldcells != NULL) {
+ (void) free((void *) lp->oldcells);
+ lp->oldcells = (unsigned char *) NULL;
+ }
+ if (lp->newcells != NULL) {
+ (void) free((void *) lp->newcells);
+ lp->newcells = (unsigned char *) NULL;
+ }
+ free_list(lp);
+}
+
+static Bool
+addtolist(ModeInfo * mi, int col, int row, unsigned char state)
+{
+ loopstruct *lp = &loops[MI_SCREEN(mi)];
+ CellList *current = lp->cellList[state];
+
+ if ((lp->cellList[state] = (CellList *) malloc(sizeof (CellList))) ==
+ NULL) {
+ lp->cellList[state] = current;
+ free_loop(MI_DISPLAY(mi), lp);
+ return False;
+ }
+ lp->cellList[state]->pt.x = col;
+ lp->cellList[state]->pt.y = row;
+ lp->cellList[state]->next = current;
+ lp->ncells[state]++;
+ return True;
+}
+
+static Bool
draw_state(ModeInfo * mi, int state)
{
loopstruct *lp = &loops[MI_SCREEN(mi)];
+ Display *display = MI_DISPLAY(mi);
GC gc;
XGCValues gcv;
CellList *current = lp->cellList[state];
if (MI_NPIXELS(mi) >= COLORS) {
gc = MI_GC(mi);
- XSetForeground(MI_DISPLAY(mi), gc, lp->colors[state]);
+ XSetForeground(display, gc, lp->colors[state]);
} else {
+#ifdef DO_STIPPLE
gcv.stipple = lp->pixmaps[state];
+#endif /* DO_STIPPLE */
gcv.foreground = MI_WHITE_PIXEL(mi);
gcv.background = MI_BLACK_PIXEL(mi);
- XChangeGC(MI_DISPLAY(mi), lp->stippledGC,
- GCStipple | GCForeground | GCBackground, &gcv);
+ XChangeGC(display, lp->stippledGC,
+#ifdef DO_STIPPLE
+ GCStipple |
+#endif /* DO_STIPPLE */
+ GCForeground | GCBackground, &gcv);
gc = lp->stippledGC;
}
lp->shape.hexagon[0].x = lp->xb + ccol * lp->xs;
lp->shape.hexagon[0].y = lp->yb + crow * lp->ys;
if (lp->xs == 1 && lp->ys == 1)
- XFillRectangle(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
- lp->shape.hexagon[0].x, lp->shape.hexagon[0].y, 1, 1);
+ XDrawPoint(display, MI_WINDOW(mi), gc,
+ lp->shape.hexagon[0].x, lp->shape.hexagon[0].y);
else
- XFillPolygon(MI_DISPLAY(mi), MI_WINDOW(mi), gc,
+ XFillPolygon(display, MI_WINDOW(mi), gc,
lp->shape.hexagon, 6, Convex, CoordModePrevious);
current = current->next;
}
} else {
/* Take advantage of XFillRectangles */
- XRectangle *rects = NULL;
+ XRectangle *rects;
int nrects = 0;
/* Create Rectangle list from part of the cellList */
- if ((rects = (XRectangle *) malloc(lp->ncells[state] * sizeof (XRectangle))) == NULL) {
- return;
+ if ((rects = (XRectangle *) malloc(lp->ncells[state] *
+ sizeof (XRectangle))) == NULL) {
+ return False;
}
while (current) {
nrects++;
}
/* Finally get to draw */
- XFillRectangles(MI_DISPLAY(mi), MI_WINDOW(mi), gc, rects, nrects);
+ XFillRectangles(display, MI_WINDOW(mi), gc, rects, nrects);
/* Free up rects list and the appropriate part of the cellList */
(void) free((void *) rects);
}
free_state(lp, state);
- XFlush(MI_DISPLAY(mi));
+ return True;
}
-static int
+static Bool
init_table(void)
{
if (table == NULL) {
mult *= 8;
if ((table = (unsigned int *) calloc(mult, sizeof (unsigned int))) == NULL) {
- return 1;
+ return False;
}
+
#ifdef RAND_RULES
/* Here I was interested to see what happens when it hits a wall....
Rules not normally used take over... takes too much time though */
- {
+ /* Each state = 3 bits */
+ if (MAXRAND < 16777216.0) {
for (j = 0; j < mult; j++) {
- for (k = 0; k < 8; k++)
- table[j] |= (unsigned int) ((unsigned int) (NRAND(8)) << (k * 3));
+ table[j] = (unsigned int) ((NRAND(4096) << 12) & NRAND(4096));
+ }
+ } else {
+ for (j = 0; j < mult; j++) {
+ table[j] = (unsigned int) (NRAND(16777216));
}
}
#endif
for (k = 0; k < local_neighbors; k++) {
TRANSITION(tt, n[k]);
}
- TRANSITION(tt, c);
+ FINALTRANSITION(tt, c);
HEX_TABLE_IN(c, n[0], n[1], n[2], n[3], n[4], n[5], i);
HEX_TABLE_IN(c, n[1], n[2], n[3], n[4], n[5], n[0], i);
HEX_TABLE_IN(c, n[2], n[3], n[4], n[5], n[0], n[1], i);
for (k = 0; k < local_neighbors; k++) {
TRANSITION(tt, n[k]);
}
- TRANSITION(tt, c);
+ FINALTRANSITION(tt, c);
TABLE_IN(c, n[0], n[1], n[2], n[3], i);
TABLE_IN(c, n[1], n[2], n[3], n[0], i);
TABLE_IN(c, n[2], n[3], n[0], n[1], i);
}
}
}
- return 0;
+ return True;
+}
+
+static void
+init_flaw(ModeInfo * mi)
+{
+ loopstruct *lp = &loops[MI_SCREEN(mi)];
+ int a, b;
+
+#define BLUE 2
+ if (lp->bncols <= 3 || lp->bnrows <= 3)
+ return;
+ a = MIN(lp->bncols - 3, 2 * ((local_neighbors == 6) ?
+ HEX_MINGRIDSIZE : MINGRIDSIZE));
+ a = NRAND(a) + (lp->bncols - a) / 2;
+ b = MIN(lp->bnrows - 3, 2 * ((local_neighbors == 6) ?
+ HEX_MINGRIDSIZE : MINGRIDSIZE));
+ b = NRAND(b) + (lp->bnrows - b) / 2;
+ if (lp->mincol > a)
+ lp->mincol = a;
+ if (lp->minrow > b)
+ lp->minrow = b;
+ if (lp->maxcol < a + 2)
+ lp->maxcol = a + 2;
+ if (lp->maxrow < b + 2)
+ lp->maxrow = b + 2;
+
+ if (local_neighbors == 6) {
+ lp->newcells[b * lp->bncols + a + !(b % 2) ] = BLUE;
+ lp->newcells[b * lp->bncols + a + 1 + !(b % 2)] = BLUE;
+ lp->newcells[(b + 1) * lp->bncols + a] = BLUE;
+ lp->newcells[(b + 1) * lp->bncols + a + 2] = BLUE;
+ lp->newcells[(b + 2) * lp->bncols + a + !(b % 2)] = BLUE;
+ lp->newcells[(b + 2) * lp->bncols + a + 1 + !(b % 2)] = BLUE;
+ } else {
+ int orient = NRAND(4);
+ lp->newcells[lp->bncols * (b + 1) + a + 1] = BLUE;
+ if (orient == 0 || orient == 1) {
+ lp->newcells[lp->bncols * b + a + 1] = BLUE;
+ }
+ if (orient == 1 || orient == 2) {
+ lp->newcells[lp->bncols * (b + 1) + a + 2] = BLUE;
+ }
+ if (orient == 2 || orient == 3) {
+ lp->newcells[lp->bncols * (b + 2) + a + 1] = BLUE;
+ }
+ if (orient == 3 || orient == 0) {
+ lp->newcells[lp->bncols * (b + 1) + a] = BLUE;
+ }
+ }
}
static void
init_adam(ModeInfo * mi)
{
loopstruct *lp = &loops[MI_SCREEN(mi)];
- XPoint start, dirx, diry;
- int i, j;
+ XPoint start = { 0, 0 }, dirx = { 0, 0 }, diry = { 0, 0 };
+ int i, j, dir;
- if (local_neighbors == 6) {
+#ifdef DELAYDEBUGLOOP
+ lp->clockwise = 0;
+ if (!MI_COUNT(mi)) /* Probably doing testing so do not confuse */
+#endif
+ lp->clockwise = (Bool) (LRAND() & 1);
+#ifdef DELAYDEBUGLOOP
+ dir = 0;
+ if (!MI_COUNT(mi)) /* Probably doing testing so do not confuse */
+#endif
+ dir = NRAND(local_neighbors);
+ if (local_neighbors == 6) {
int k;
- /* switch (0) */
- switch (NRAND(6)) {
+ switch (dir) {
case 0:
start.x = (lp->bncols - HEX_ADAM_LOOPX / 2) / 2;
start.y = (lp->bnrows - HEX_ADAM_LOOPY) / 2;
- lp->mincol = start.x - 2;
- lp->minrow = start.y - 1;
- lp->maxcol = start.x + HEX_ADAM_LOOPX + 1;
- lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
+ if (lp->mincol > start.x - 2)
+ lp->mincol = start.x - 2;
+ if (lp->minrow > start.y - 1)
+ lp->minrow = start.y - 1;
+ if (lp->maxcol < start.x + HEX_ADAM_LOOPX + 1)
+ lp->maxcol = start.x + HEX_ADAM_LOOPX + 1;
+ if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1)
+ lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
for (j = 0; j < HEX_ADAM_LOOPY; j++) {
for (i = 0; i < HEX_ADAM_LOOPX; i++) {
k = (((lp->bnrows / 2 + HEX_ADAM_LOOPY / 2) % 2) ? -j / 2 : -(j + 1) / 2);
lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] =
- hex_self_reproducing_loop[j][i];
+ (lp->clockwise) ?
+ hex_self_reproducing_loop[i][j] :
+ hex_self_reproducing_loop[j][i];
}
}
break;
case 1:
start.x = (lp->bncols - (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) / 2;
start.y = (lp->bnrows - HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2;
- lp->mincol = start.x - 1;
- lp->minrow = start.y - HEX_ADAM_LOOPX;
- lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1;
- lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
+ if (lp->mincol > start.x - 1)
+ lp->mincol = start.x - 1;
+ if (lp->minrow > start.y - HEX_ADAM_LOOPX)
+ lp->minrow = start.y - HEX_ADAM_LOOPX;
+ if (lp->maxcol < start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1)
+ lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1;
+ if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1)
+ lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
for (j = 0; j < HEX_ADAM_LOOPY; j++) {
for (i = 0; i < HEX_ADAM_LOOPX; i++) {
k = (((lp->bnrows / 2 + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) % 2)
? -(i + j + 1) / 2 : -(i + j) / 2);
lp->newcells[(start.y + j - i) * lp->bncols + start.x + i + j + k] =
- hex_self_reproducing_loop[j][i];
+ (lp->clockwise) ?
+ hex_self_reproducing_loop[i][j] :
+ hex_self_reproducing_loop[j][i];
}
}
break;
case 2:
start.x = (lp->bncols - HEX_ADAM_LOOPY / 2) / 2;
start.y = (lp->bnrows - HEX_ADAM_LOOPX) / 2;
- lp->mincol = start.x - 2;
- lp->minrow = start.y - 1;
- lp->maxcol = start.x + HEX_ADAM_LOOPY + 1;
- lp->maxrow = start.y + HEX_ADAM_LOOPX + 1;
+ if (lp->mincol > start.x - 2)
+ lp->mincol = start.x - 2;
+ if (lp->minrow > start.y - 1)
+ lp->minrow = start.y - 1;
+ if (lp->maxcol < start.x + HEX_ADAM_LOOPX + 1)
+ lp->maxcol = start.x + HEX_ADAM_LOOPX + 1;
+ if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1)
+ lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
for (j = 0; j < HEX_ADAM_LOOPX; j++) {
for (i = 0; i < HEX_ADAM_LOOPY; i++) {
k = (((lp->bnrows / 2 + HEX_ADAM_LOOPX / 2) % 2) ? -(HEX_ADAM_LOOPX - j - 1) / 2 : -(HEX_ADAM_LOOPX - j) / 2);
lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] =
- hex_self_reproducing_loop[i][HEX_ADAM_LOOPX - j - 1];
+ (lp->clockwise) ?
+ hex_self_reproducing_loop[j][HEX_ADAM_LOOPX - i - 1] :
+ hex_self_reproducing_loop[i][HEX_ADAM_LOOPY - j - 1];
}
}
break;
case 3:
start.x = (lp->bncols - HEX_ADAM_LOOPX / 2) / 2;
start.y = (lp->bnrows - HEX_ADAM_LOOPY) / 2;
- lp->mincol = start.x - 1, lp->minrow = start.y - 1;
- lp->maxcol = start.x + HEX_ADAM_LOOPX + 1, lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
+ if (lp->mincol > start.x - 1)
+ lp->mincol = start.x - 1;
+ if (lp->minrow > start.y - 1)
+ lp->minrow = start.y - 1;
+ if (lp->maxcol < start.x + HEX_ADAM_LOOPX + 1)
+ lp->maxcol = start.x + HEX_ADAM_LOOPX + 1;
+ if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1)
+ lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
for (j = 0; j < HEX_ADAM_LOOPY; j++) {
for (i = 0; i < HEX_ADAM_LOOPX; i++) {
k = (((lp->bnrows / 2 + HEX_ADAM_LOOPY / 2) % 2) ? -j / 2 : -(j + 1) / 2);
lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] =
- hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1];
+ (lp->clockwise) ?
+ hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][HEX_ADAM_LOOPY - j - 1] :
+ hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1];
}
}
break;
case 4:
start.x = (lp->bncols - (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) / 2;
start.y = (lp->bnrows - HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2;
- lp->mincol = start.x - 1;
- lp->minrow = start.y - HEX_ADAM_LOOPX;
- lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1;
- lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
+ if (lp->mincol > start.x - 1)
+ lp->mincol = start.x - 1;
+ if (lp->minrow > start.y - HEX_ADAM_LOOPX)
+ lp->minrow = start.y - HEX_ADAM_LOOPX;
+ if (lp->maxcol < start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1)
+ lp->maxcol = start.x + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2 + 1;
+ if (lp->maxrow < start.y + HEX_ADAM_LOOPY + 1)
+ lp->maxrow = start.y + HEX_ADAM_LOOPY + 1;
for (j = 0; j < HEX_ADAM_LOOPY; j++) {
for (i = 0; i < HEX_ADAM_LOOPX; i++) {
k = (((lp->bnrows / 2 + (HEX_ADAM_LOOPX + HEX_ADAM_LOOPY) / 2) % 2)
? -(i + j + 1) / 2 : -(i + j) / 2);
lp->newcells[(start.y + j - i) * lp->bncols + start.x + i + j + k] =
- hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1];
+ (lp->clockwise) ?
+ hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][HEX_ADAM_LOOPY - j - 1] :
+ hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][HEX_ADAM_LOOPX - i - 1];
}
}
break;
case 5:
start.x = (lp->bncols - HEX_ADAM_LOOPY / 2) / 2;
start.y = (lp->bnrows - HEX_ADAM_LOOPX) / 2;
- lp->mincol = start.x - 2;
- lp->minrow = start.y - 1;
- lp->maxcol = start.x + HEX_ADAM_LOOPY + 1;
- lp->maxrow = start.y + HEX_ADAM_LOOPX + 1;
+ if (lp->mincol > start.x - 2)
+ lp->mincol = start.x - 2;
+ if (lp->minrow > start.y - 1)
+ lp->minrow = start.y - 1;
+ if (lp->maxcol < start.x + HEX_ADAM_LOOPY + 1)
+ lp->maxcol = start.x + HEX_ADAM_LOOPY + 1;
+ if (lp->maxrow < start.y + HEX_ADAM_LOOPX + 1)
+ lp->maxrow = start.y + HEX_ADAM_LOOPX + 1;
for (j = 0; j < HEX_ADAM_LOOPX; j++) {
for (i = 0; i < HEX_ADAM_LOOPY; i++) {
k = (((lp->bnrows / 2 + HEX_ADAM_LOOPX / 2) % 2) ? -(HEX_ADAM_LOOPX - j - 1) / 2 : -(HEX_ADAM_LOOPX - j) / 2);
lp->newcells[(start.y + j) * lp->bncols + start.x + i + k] =
- hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][j];
+ (lp->clockwise) ?
+ hex_self_reproducing_loop[HEX_ADAM_LOOPY - j - 1][i] :
+ hex_self_reproducing_loop[HEX_ADAM_LOOPX - i - 1][j];
}
}
break;
}
#if DEBUGTEST
- /* printf ("s %d s %d \n", start.x, start.y); */
- printf ("%d %d %d %d %d\t",
+ /* (void) printf ("s %d s %d \n", start.x, start.y); */
+ (void) printf ("%d %d %d %d %d\n",
start.x + i + ((lp->bnrows / 2 % 2) ? -j / 2 : -(j + 1) / 2) - lp->bx,
start.y + j - lp->by, i, j, hex_self_reproducing_loop[j][i]);
/* Draw right away */
drawcell(mi, start.x + i + ((lp->bnrows / 2 % 2) ? -j / 2 : -(j + 1) / 2) - lp->bx,
start.y + j - lp->by,
hex_self_reproducing_loop[j][i]);
-#endif
-#if DEBUGTEST
- printf ("\n");
-#endif
-#if DEBUGTEST
- printf ("\n");
#endif
} else {
- switch (NRAND(4)) {
+ switch (dir) {
case 0:
start.x = (lp->bncols - ADAM_LOOPX) / 2;
start.y = (lp->bnrows - ADAM_LOOPY) / 2;
dirx.x = 1, dirx.y = 0;
diry.x = 0, diry.y = 1;
- lp->mincol = start.x, lp->minrow = start.y;
- lp->maxcol = start.x + ADAM_LOOPX, lp->maxrow = start.y + ADAM_LOOPY;
+ if (lp->mincol > start.x)
+ lp->mincol = start.x;
+ if (lp->minrow > start.y)
+ lp->minrow = start.y;
+ if (lp->maxcol < start.x + ADAM_LOOPX)
+ lp->maxcol = start.x + ADAM_LOOPX;
+ if (lp->maxrow < start.y + ADAM_LOOPY)
+ lp->maxrow = start.y + ADAM_LOOPY;
break;
case 1:
start.x = (lp->bncols + ADAM_LOOPY) / 2;
start.y = (lp->bnrows - ADAM_LOOPX) / 2;
dirx.x = 0, dirx.y = 1;
diry.x = -1, diry.y = 0;
- lp->mincol = start.x - ADAM_LOOPY, lp->minrow = start.y;
- lp->maxcol = start.x, lp->maxrow = start.y + ADAM_LOOPX;
+ if (lp->mincol > start.x - ADAM_LOOPY)
+ lp->mincol = start.x - ADAM_LOOPY;
+ if (lp->minrow > start.y)
+ lp->minrow = start.y;
+ if (lp->maxcol < start.x)
+ lp->maxcol = start.x;
+ if (lp->maxrow < start.y + ADAM_LOOPX)
+ lp->maxrow = start.y + ADAM_LOOPX;
break;
case 2:
start.x = (lp->bncols + ADAM_LOOPX) / 2;
start.y = (lp->bnrows + ADAM_LOOPY) / 2;
dirx.x = -1, dirx.y = 0;
diry.x = 0, diry.y = -1;
- lp->mincol = start.x - ADAM_LOOPX, lp->minrow = start.y - ADAM_LOOPY;
- lp->maxcol = start.x, lp->maxrow = start.y;
+ if (lp->mincol > start.x - ADAM_LOOPX)
+ lp->mincol = start.x - ADAM_LOOPX;
+ if (lp->minrow > start.y - ADAM_LOOPY)
+ lp->minrow = start.y - ADAM_LOOPY;
+ if (lp->maxcol < start.x)
+ lp->maxcol = start.x;
+ if (lp->maxrow < start.y)
+ lp->maxrow = start.y;
break;
case 3:
start.x = (lp->bncols - ADAM_LOOPY) / 2;
start.y = (lp->bnrows + ADAM_LOOPX) / 2;
dirx.x = 0, dirx.y = -1;
diry.x = 1, diry.y = 0;
- lp->mincol = start.x, lp->minrow = start.y - ADAM_LOOPX;
- lp->maxcol = start.x + ADAM_LOOPY, lp->maxrow = start.y;
+ if (lp->mincol > start.x)
+ lp->mincol = start.x;
+ if (lp->minrow > start.y - ADAM_LOOPX)
+ lp->minrow = start.y - ADAM_LOOPX;
+ if (lp->maxcol < start.x + ADAM_LOOPX)
+ lp->maxcol = start.x + ADAM_LOOPX;
+ if (lp->maxrow < start.y)
+ lp->maxrow = start.y;
break;
}
for (j = 0; j < ADAM_LOOPY; j++)
for (i = 0; i < ADAM_LOOPX; i++)
- lp->newcells[(start.y + dirx.y * i + diry.y * j) * lp->bncols +
- start.x + dirx.x * i + diry.x * j] =
- self_reproducing_loop[j][i];
+ lp->newcells[lp->bncols * (start.y + dirx.y * i + diry.y * j) +
+ start.x + dirx.x * i + diry.x * j] =
+ (lp->clockwise) ?
+ self_reproducing_loop[j][ADAM_LOOPX - i - 1] :
+ self_reproducing_loop[j][i];
#if DEBUG
/* Draw right away */
drawcell(mi, start.x + dirx.x * i + diry.x * j - lp->bx,
start.y + dirx.y * i + diry.y * j - lp->by,
- self_reproducing_loop[j][i]);
+ (lp->clockwise) ? self_reproducing_loop[j][ADAM_LOOPX - i - i] : self_reproducing_loop[j][i]);
#endif
}
}
}
}
if (local_neighbors == 6) {
- *z = HEX_TABLE_OUT(c, n[0], n[1], n[2], n[3], n[4], n[5]);
+ *z = (lp->clockwise) ?
+ HEX_TABLE_OUT(c, n[5], n[4], n[3], n[2], n[1], n[0]) :
+ HEX_TABLE_OUT(c, n[0], n[1], n[2], n[3], n[4], n[5]);
} else {
- *z = TABLE_OUT(c, n[0], n[1], n[2], n[3]);
+ *z = (lp->clockwise) ?
+ TABLE_OUT(c, n[3], n[2], n[1], n[0]) :
+ TABLE_OUT(c, n[0], n[1], n[2], n[3]);
}
}
}
}
-static void
-free_list(loopstruct * lp)
-{
- int state;
-
- for (state = 0; state < COLORS; state++)
- free_state(lp, state);
-}
-
-void
-release_loop(ModeInfo * mi)
+ENTRYPOINT void
+release_loop (ModeInfo * mi)
{
if (loops != NULL) {
int screen;
- for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
- loopstruct *lp = &loops[screen];
- int shade;
-
- for (shade = 0; shade < lp->init_bits; shade++)
- if (lp->pixmaps[shade] != None)
- XFreePixmap(MI_DISPLAY(mi), lp->pixmaps[shade]);
- if (lp->stippledGC != None)
- XFreeGC(MI_DISPLAY(mi), lp->stippledGC);
- if (lp->oldcells != NULL)
- (void) free((void *) lp->oldcells);
- if (lp->newcells != NULL)
- (void) free((void *) lp->newcells);
- free_list(lp);
- }
+ for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
+ free_loop(MI_DISPLAY(mi), &loops[screen]);
(void) free((void *) loops);
- loops = NULL;
+ loops = (loopstruct *) NULL;
}
if (table != NULL) {
(void) free((void *) table);
- table = NULL;
+ table = (unsigned int *) NULL;
}
}
-void
-init_loop(ModeInfo * mi)
+static void *stop_warning_about_triangleUnit_already;
+
+
+ENTRYPOINT void
+init_loop (ModeInfo * mi)
{
Display *display = MI_DISPLAY(mi);
- Window window = MI_WINDOW(mi);
int i, size = MI_SIZE(mi);
loopstruct *lp;
- XGCValues gcv;
+
+ stop_warning_about_triangleUnit_already = (void *) &triangleUnit;
if (loops == NULL) {
if ((loops = (loopstruct *) calloc(MI_NUM_SCREENS(mi),
lp->redrawing = 0;
+#ifdef DO_STIPPLE
if ((MI_NPIXELS(mi) < COLORS) && (lp->init_bits == 0)) {
- if (lp->stippledGC == None) {
+ Window window = MI_WINDOW(mi);
+ XGCValues gcv;
+ if (lp->stippledGC == None) {
gcv.fill_style = FillOpaqueStippled;
- lp->stippledGC = XCreateGC(display, window, GCFillStyle, &gcv);
- if (lp->stippledGC == None) {
- release_loop(mi);
+ if ((lp->stippledGC = XCreateGC(display, window,
+ GCFillStyle, &gcv)) == None) {
+ free_loop(display, lp);
return;
}
}
LOOPBITS(stipples[7], STIPPLESIZE, STIPPLESIZE);
LOOPBITS(stipples[8], STIPPLESIZE, STIPPLESIZE);
LOOPBITS(stipples[10], STIPPLESIZE, STIPPLESIZE);
- if (lp->pixmaps[COLORS - 1] == None) {
- release_loop(mi);
- return;
- }
}
+#endif /* DO_STIPPLE */
if (MI_NPIXELS(mi) >= COLORS) {
/* Maybe these colors should be randomized */
lp->colors[0] = MI_BLACK_PIXEL(mi);
lp->width = MI_WIDTH(mi);
lp->height = MI_HEIGHT(mi);
- if (!local_neighbors) {
- for (i = 0; i < NEIGHBORKINDS; i++) {
- if (neighbors == plots[i]) {
- local_neighbors = neighbors;
- neighbor_kind = i;
- break;
- }
+ if (!local_neighbors) {
+ for (i = 0; i < NEIGHBORKINDS; i++) {
+ if (neighbors == plots[i]) {
+ local_neighbors = neighbors;
+ break;
+ }
if (i == NEIGHBORKINDS - 1) {
-
#if 1
local_neighbors = plots[NRAND(NEIGHBORKINDS)];
- neighbor_kind = (local_neighbors == 4) ? 0 : 1;
#else
local_neighbors = 4;
- neighbor_kind = 0;
#endif
break;
}
if (local_neighbors == 6) {
int nccols, ncrows;
- if (lp->width < 4)
- lp->width = 4;
- if (lp->height < 4)
- lp->height = 4;
+ if (lp->width < 8)
+ lp->width = 8;
+ if (lp->height < 8)
+ lp->height = 8;
if (size < -MINSIZE) {
lp->ys = NRAND(MIN(-size, MAX(MINSIZE, MIN(lp->width, lp->height) /
HEX_MINGRIDSIZE)) - MINSIZE + 1) + MINSIZE;
lp->ys = MIN(size, MAX(MINSIZE, MIN(lp->width, lp->height) /
HEX_MINGRIDSIZE));
lp->xs = lp->ys;
- nccols = MAX(lp->width / lp->xs - 2, HEX_ADAM_LOOPX + 1);
- ncrows = MAX(lp->height / lp->ys - 1, HEX_ADAM_LOOPY + 1);
+ nccols = MAX(lp->width / lp->xs - 2, HEX_MINGRIDSIZE);
+ ncrows = MAX(lp->height / lp->ys - 1, HEX_MINGRIDSIZE);
lp->ncols = nccols / 2;
lp->nrows = ncrows / 2;
- lp->nrows -= !(lp->nrows & 1); /* Must be odd */
+ lp->nrows -= !(lp->nrows & 1); /* Must be odd */
lp->xb = (lp->width - lp->xs * nccols) / 2 + lp->xs;
lp->yb = (lp->height - lp->ys * ncrows) / 2 + lp->ys;
for (i = 0; i < 6; i++) {
if (lp->oldcells != NULL) {
(void) free((void *) lp->oldcells);
- lp->oldcells = NULL;
- }
- if ((lp->oldcells = (unsigned char *) calloc(lp->bncols * lp->bnrows, sizeof (unsigned char))) == NULL) {
- release_loop(mi);
+ lp->oldcells = (unsigned char *) NULL;
+ }
+ if ((lp->oldcells = (unsigned char *) calloc(lp->bncols * lp->bnrows,
+ sizeof (unsigned char))) == NULL) {
+ free_loop(display, lp);
return;
}
if (lp->newcells != NULL) {
(void) free((void *) lp->newcells);
- lp->newcells = NULL;
+ lp->newcells = (unsigned char *) NULL;
}
- if ((lp->newcells = (unsigned char *) calloc(lp->bncols * lp->bnrows, sizeof (unsigned char))) == NULL) {
- release_loop(mi);
+ if ((lp->newcells = (unsigned char *) calloc(lp->bncols * lp->bnrows,
+ sizeof (unsigned char))) == NULL) {
+ free_loop(display, lp);
return;
}
- if (init_table()) {
+ if (!init_table()) {
release_loop(mi);
return;
}
+ lp->mincol = lp->bncols - 1;
+ lp->minrow = lp->bnrows - 1;
+ lp->maxcol = 0;
+ lp->maxrow = 0;
+#ifndef DELAYDEBUGLOOP
+ {
+ int flaws = MI_COUNT(mi);
+
+ if (flaws < 0)
+ flaws = NRAND(-MI_COUNT(mi) + 1);
+ for (i = 0; i < flaws; i++) {
+ init_flaw(mi);
+ }
+ /* actual flaws might be less since the adam loop done next */
+ }
+#endif
init_adam(mi);
}
-void
-draw_loop(ModeInfo * mi)
+ENTRYPOINT void
+draw_loop (ModeInfo * mi)
{
- loopstruct *lp = &loops[MI_SCREEN(mi)];
- int offset, i, j, life = 0;
+ int offset, i, j;
unsigned char *z, *znew;
+ loopstruct *lp;
- if (loops == NULL) {
- init_loop(mi);
+ if (loops == NULL)
return;
- }
+ lp = &loops[MI_SCREEN(mi)];
+ if (lp->newcells == NULL)
+ return;
+
MI_IS_DRAWN(mi) = True;
+ lp->dead = True;
+#ifdef DELAYDEBUGLOOP
+ if (MI_COUNT(mi) && lp->generation > MI_COUNT(mi)) {
+ (void) sleep(DELAYDEBUGLOOP);
+ }
+#endif
for (j = lp->minrow; j <= lp->maxrow; j++) {
for (i = lp->mincol; i <= lp->maxcol; i++) {
z = lp->oldcells + offset;
znew = lp->newcells + offset;
if (*z != *znew) {
+ lp->dead = False;
*z = *znew;
- addtolist(mi, i - lp->bx, j - lp->by, *znew);
- life = 1;
+ if (!addtolist(mi, i - lp->bx, j - lp->by, *znew))
+ return;
if (i == lp->mincol && i > lp->bx)
lp->mincol--;
if (j == lp->minrow && j > lp->by)
}
}
for (i = 0; i < COLORS; i++)
- draw_state(mi, i);
- if (++lp->generation > MI_CYCLES(mi) /* || !life */) {
+ if (!draw_state(mi, i)) {
+ free_loop(MI_DISPLAY(mi), lp);
+ return;
+ }
+ if (++lp->generation > MI_CYCLES(mi) || lp->dead) {
init_loop(mi);
return;
} else
}
}
-void
-refresh_loop(ModeInfo * mi)
+ENTRYPOINT void
+refresh_loop (ModeInfo * mi)
{
- loopstruct *lp = &loops[MI_SCREEN(mi)];
+ loopstruct *lp;
- if (loops == NULL) {
- init_loop(mi);
+ if (loops == NULL)
return;
- }
+ lp = &loops[MI_SCREEN(mi)];
+
MI_CLEARWINDOW(mi);
lp->redrawing = 1;
lp->redrawpos = lp->by * lp->ncols + lp->bx;
}
+
+XSCREENSAVER_MODULE ("Loop", loop)
+
+#endif /* MODE_loop */