http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.01.tar.gz
[xscreensaver] / hacks / penrose.c
1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* penrose --- quasiperiodic tilings */
3
4 /*  As reported in News of the Weird:
5
6           In April, Sir Roger Penrose, a British math professor who has worked
7           with Stephen Hawking on such topics as relativity, black holes, and
8           whether time has a beginning, filed a copyright-infringement lawsuit
9           against the Kimberly-Clark Corporation, which Penrose said copied a
10           pattern he created (a pattern demonstrating that "a nonrepeating
11           pattern could exist in nature") for its Kleenex quilted toilet paper.
12           Penrose said he doesn't like litigation but, "When it comes to the
13           population of Great Britain being invited by a multinational to wipe
14           their bottoms on what appears to be the work of a Knight of the
15           Realm, then a last stand must be taken."
16
17                                 NOTW #491, 4-jul-1997, by Chuck Shepherd.
18                                 http://www.nine.org/notw/notw.html
19  */
20
21 #if !defined( lint ) && !defined( SABER )
22 static const char sccsid[] = "@(#)penrose.c     5.00 2000/11/01 xlockmore";
23
24 #endif
25
26 /*-
27  * Copyright (c) 1996 by Timo Korvola <tkorvola@dopey.hut.fi>
28  *
29  * Permission to use, copy, modify, and distribute this software and its
30  * documentation for any purpose and without fee is hereby granted,
31  * provided that the above copyright notice appear in all copies and that
32  * both that copyright notice and this permission notice appear in
33  * supporting documentation.
34  *
35  * This file is provided AS IS with no warranties of any kind.  The author
36  * shall have no liability with respect to the infringement of copyrights,
37  * trade secrets or any patents by this file or any part thereof.  In no
38  * event will the author be liable for any lost revenue or profits or
39  * other special, indirect and consequential damages.
40  *
41  * Revision History:
42  * 01-Nov-2000: Allocation checks
43  * 10-May-1997: Jamie Zawinski <jwz@jwz.org> compatible with xscreensaver
44  * 09-Sep-1996: Written.
45  */
46
47 /*-
48 Be careful, this probably still has a few bugs (many of which may only
49 appear with a very low probability).  These are seen with -verbose .
50 If one of these are hit penrose will reinitialize.
51 */
52
53 /*-
54  * See Onoda, Steinhardt, DiVincenzo and Socolar in
55  * Phys. Rev. Lett. 60, #25, 1988 or
56  * Strandburg in Computers in Physics, Sep/Oct 1991.
57  *
58  * This implementation uses the simpler version of the growth
59  * algorithm, i.e., if there are no forced vertices, a randomly chosen
60  * tile is added to a randomly chosen vertex (no preference for those
61  * 108 degree angles).
62  *
63  * There are two essential differences to the algorithm presented in
64  * the literature: First, we do not allow the tiling to enclose an
65  * untiled area.  Whenever this is in danger of happening, we just
66  * do not add the tile, hoping for a better random choice the next
67  * time.  Second, when choosing a vertex randomly, we will take
68  * one that lies within the viewport if available.  If this seems to
69  * cause enclosures in the forced rule case, we will allow invisible
70  * vertices to be chosen.
71  *
72  * Tiling is restarted whenever one of the following happens: there
73  * are no incomplete vertices within the viewport or the tiling has
74  * extended a window's length beyond the edge of the window
75  * horizontally or vertically or forced rule choice has failed 100
76  * times due to areas about to become enclosed.
77  *
78  * Introductory info:
79  * Science News March 23 1985 Vol 127, No. 12
80  * Science News July 16 1988 Vol 134, No. 3
81  * The Economist Sept 17 1988 pg. 100
82  *
83  */
84
85 #ifdef STANDALONE
86 #define MODE_penrose
87 #define PROGCLASS "Penrose"
88 #define HACK_INIT init_penrose
89 #define HACK_DRAW draw_penrose
90 #define penrose_opts xlockmore_opts
91 #define DEFAULTS "*delay: 10000 \n" \
92  "*size: 40 \n" \
93  "*ncolors: 64 \n"
94 #include "xlockmore.h"          /* from the xscreensaver distribution */
95 #else /* !STANDALONE */
96 #include "xlock.h"              /* from the xlockmore distribution */
97 #endif /* !STANDALONE */
98
99 #ifdef MODE_penrose
100
101 #define DEF_AMMANN  "False"
102
103 static Bool ammann;
104
105 static XrmOptionDescRec opts[] =
106 {
107         {(char *) "-ammann", (char *) ".penrose.ammann", XrmoptionNoArg, (caddr_t) "on"},
108         {(char *) "+ammann", (char *) ".penrose.ammann", XrmoptionNoArg, (caddr_t) "off"}
109 };
110 static argtype vars[] =
111 {
112         {(caddr_t *) & ammann, (char *) "ammann", (char *) "Ammann", (char *) DEF_AMMANN, t_Bool}
113 };
114 static OptionStruct desc[] =
115 {
116         {(char *) "-/+ammann", (char *) "turn on/off Ammann lines"}
117 };
118
119 ModeSpecOpt penrose_opts =
120 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
121
122 #ifdef USE_MODULES
123 ModStruct   penrose_description =
124 {"penrose", "init_penrose", "draw_penrose", "release_penrose",
125  "init_penrose", "init_penrose", (char *) NULL, &penrose_opts,
126  10000, 1, 1, -40, 64, 1.0, "",
127  "Shows Penrose's quasiperiodic tilings", 0, NULL};
128
129 #endif
130
131 /*-
132  * Annoyingly the ANSI C library people have reserved all identifiers
133  * ending with _t for future use.  Hence we use _c as a suffix for
134  * typedefs (c for class, although this is not C++).
135  */
136
137 #define MINSIZE 5
138
139 /*-
140  * In theory one could fit 10 tiles to a single vertex.  However, the
141  * vertex rules only allow at most seven tiles to meet at a vertex.
142  */
143
144 #define CELEBRATE 31415         /* This causes a pause, an error occurred. */
145 #define COMPLETION 3141         /* This causes a pause, tiles filled up screen. */
146
147 #define MAX_TILES_PER_VERTEX 7
148 #define N_VERTEX_RULES 8
149 #define ALLOC_NODE(type) (type *)malloc(sizeof (type))
150
151 /*-
152  * These are used to specify directions.  They can also be used in bit
153  * masks to specify a combination of directions.
154  */
155 #define S_LEFT 1
156 #define S_RIGHT 2
157
158
159 /*-
160  * We do not actually maintain objects corresponding to the tiles since
161  * we do not really need them and they would only consume memory and
162  * cause additional bookkeeping.  Instead we only have vertices, and
163  * each vertex lists the type of each adjacent tile as well as the
164  * position of the vertex on the tile (hereafter refered to as
165  * "corner").  These positions are numbered in counterclockwise order
166  * so that 0 is where two double arrows meet (see one of the
167  * articles).  The tile type and vertex number are stored in a single
168  * integer (we use char, and even most of it remains unused).
169  *
170  * The primary use of tile objects would be draw traversal, but we do
171  * not currently do redraws at all (we just start over).
172  */
173 #define VT_CORNER_MASK 0x3
174 #define VT_TYPE_MASK 0x4
175 #define VT_THIN 0
176 #define VT_THICK 0x4
177 #define VT_BITS 3
178 #define VT_TOTAL_MASK 0x7
179
180 typedef unsigned char vertex_type_c;
181
182 /*-
183  * These allow one to compute the types of the other corners of the tile.  If
184  * you are standing at a vertex of type vt looking towards the middle of the
185  * tile, VT_LEFT( vt) is the vertex on your left etc.
186  */
187 #define VT_LEFT( vt) ((((vt) - 1) & VT_CORNER_MASK) | (((vt) & VT_TYPE_MASK)))
188 #define VT_RIGHT( vt) ((((vt) + 1) & VT_CORNER_MASK) | (((vt) & VT_TYPE_MASK)))
189 #define VT_FAR( vt) ((vt) ^ 2)
190
191
192 /*-
193  * Since we do not do redraws, we only store the vertices we need.  These are
194  * the ones with still some empty space around them for the growth algorithm
195  * to fill.
196  *
197  * Here we use a doubly chained ring-like structure as vertices often need
198  * to be removed or inserted (they are kept in geometrical order
199  * circling the tiled area counterclockwise).  The ring is refered to by
200  * a pointer to one more or less random node.  When deleting nodes one
201  * must make sure that this pointer continues to refer to a valid
202  * node.  A vertex count is maintained to make it easier to pick
203  * vertices randomly.
204  */
205 typedef struct forced_node forced_node_c;
206
207 typedef struct fringe_node {
208         struct fringe_node *prev;
209         struct fringe_node *next;
210         /* These are numbered counterclockwise.  The gap, if any, lies
211            between the last and first tiles.  */
212         vertex_type_c tiles[MAX_TILES_PER_VERTEX];
213         int         n_tiles;
214         /* A bit mask used to indicate vertex rules that are still applicable for
215            completing this vertex.  Initialize this to (1 << N_VERTEX_RULES) - 1,
216            i.e., all ones, and the rule matching functions will automatically mask
217            out rules that no longer match. */
218         unsigned char rule_mask;
219         /* If the vertex is on the forced vertex list, this points to the
220            pointer to the appropriate node in the list.  To remove the
221            vertex from the list just set *list_ptr to the next node,
222            deallocate and decrement node count. */
223         struct forced_node **list_ptr;
224         /* Screen coordinates. */
225         XPoint      loc;
226         /* We also keep track of 5D coordinates to avoid rounding errors.
227            These are in units of edge length. */
228         int         fived[5];
229         /* This is used to quickly check if a vertex is visible. */
230         unsigned char off_screen;
231 } fringe_node_c;
232
233 typedef struct {
234         fringe_node_c *nodes;
235         /* This does not count off-screen nodes. */
236         int         n_nodes;
237 } fringe_c;
238
239
240 /*-
241  * The forced vertex pool contains vertices where at least one
242  * side of the tiled region can only be extended in one way.  Note
243  * that this does not necessarily mean that there would only be one
244  * applicable rule.  forced_sides are specified using S_LEFT and
245  * S_RIGHT as if looking at the untiled region from the vertex.
246  */
247 struct forced_node {
248         fringe_node_c *vertex;
249         unsigned    forced_sides;
250         struct forced_node *next;
251 };
252
253 typedef struct {
254         forced_node_c *first;
255         int         n_nodes, n_visible;
256 } forced_pool_c;
257
258
259 /* This is the data related to the tiling of one screen. */
260 typedef struct {
261         int         width, height;
262         XPoint      origin;
263         int         edge_length;
264         fringe_c    fringe;
265         forced_pool_c forced;
266         int         done, failures;
267         unsigned long thick_color, thin_color;
268         int         busyLoop;
269         Bool        ammann;
270 } tiling_c;
271
272 static tiling_c *tilings = (tiling_c *) NULL;
273
274 /* The tiles are listed in counterclockwise order. */
275 typedef struct {
276         vertex_type_c tiles[MAX_TILES_PER_VERTEX];
277         int         n_tiles;
278 } vertex_rule_c;
279
280 static vertex_rule_c vertex_rules[N_VERTEX_RULES] =
281 {
282         {
283   {VT_THICK | 2, VT_THICK | 2, VT_THICK | 2, VT_THICK | 2, VT_THICK | 2}, 5},
284         {
285   {VT_THICK | 0, VT_THICK | 0, VT_THICK | 0, VT_THICK | 0, VT_THICK | 0}, 5},
286         {
287                 {VT_THICK | 0, VT_THICK | 0, VT_THICK | 0, VT_THIN | 0}, 4},
288         {
289          {VT_THICK | 2, VT_THICK | 2, VT_THIN | 1, VT_THIN | 3, VT_THICK | 2,
290           VT_THIN | 1, VT_THIN | 3}, 7},
291         {
292                 {VT_THICK | 2, VT_THICK | 2, VT_THICK | 2, VT_THICK | 2,
293                  VT_THIN | 1, VT_THIN | 3}, 6},
294         {
295                 {VT_THICK | 1, VT_THICK | 3, VT_THIN | 2}, 3},
296         {
297                 {VT_THICK | 0, VT_THIN | 0, VT_THIN | 0}, 3},
298         {
299      {VT_THICK | 2, VT_THIN | 1, VT_THICK | 3, VT_THICK | 1, VT_THIN | 3}, 5}
300 };
301
302
303 /* Match information returned by match_rules. */
304 typedef struct {
305         int         rule;
306         int         pos;
307 } rule_match_c;
308
309
310 /* Occasionally floating point coordinates are needed. */
311 typedef struct {
312         float       x, y;
313 } fcoord_c;
314
315
316 /* All angles are measured in multiples of 36 degrees. */
317 typedef int angle_c;
318
319 static angle_c vtype_angles[] =
320 {4, 1, 4, 1, 2, 3, 2, 3};
321
322 #define vtype_angle( v) (vtype_angles[ v])
323
324
325 /* Direction angle of an edge. */
326 static      angle_c
327 vertex_dir(ModeInfo * mi, fringe_node_c * vertex, unsigned side)
328 {
329         tiling_c   *tp = &tilings[MI_SCREEN(mi)];
330         fringe_node_c *v2 =
331         (side == S_LEFT ? vertex->next : vertex->prev);
332         register int i;
333
334         for (i = 0; i < 5; i++)
335                 switch (v2->fived[i] - vertex->fived[i]) {
336                         case 1:
337                                 return 2 * i;
338                         case -1:
339                                 return (2 * i + 5) % 10;
340                 }
341         tp->done = True;
342         if (MI_IS_VERBOSE(mi)) {
343                 (void) fprintf(stderr,
344                        "Weirdness in vertex_dir (this has been reported)\n");
345                 for (i = 0; i < 5; i++)
346                         (void) fprintf(stderr, "v2->fived[%d]=%d, vertex->fived[%d]=%d\n",
347                                        i, v2->fived[i], i, vertex->fived[i]);
348         }
349         tp->busyLoop = CELEBRATE;
350         return 0;
351 }
352
353
354 /* Move one step to a given direction. */
355 static void
356 add_unit_vec(angle_c dir, int *fived)
357 {
358         static int  dir2i[] =
359         {0, 3, 1, 4, 2};
360
361         while (dir < 0)
362                 dir += 10;
363         fived[dir2i[dir % 5]] += (dir % 2 ? -1 : 1);
364 }
365
366
367 /* For comparing coordinates. */
368 #define fived_equal( f1, f2) (!memcmp( (f1), (f2), 5 * sizeof( int)))
369
370
371 /*-
372  * This computes screen coordinates from 5D representation.  Note that X
373  * uses left-handed coordinates (y increases downwards).
374  */
375 static void
376 fived_to_loc(int fived[], tiling_c * tp, XPoint *pt)
377 {
378         static fcoord_c fived_table[5] =
379         {
380                 {.0, .0}};
381         float       fifth = 8 * atan(1.) / 5;
382         register int i;
383         register float r;
384         register fcoord_c offset;
385
386         *pt = tp->origin;
387         offset.x = 0.0;
388         offset.y = 0.0;
389         if (fived_table[0].x == .0)
390                 for (i = 0; i < 5; i++) {
391                         fived_table[i].x = cos(fifth * i);
392                         fived_table[i].y = sin(fifth * i);
393                 }
394         for (i = 0; i < 5; i++) {
395                 r = fived[i] * tp->edge_length;
396                 offset.x += r * fived_table[i].x;
397                 offset.y -= r * fived_table[i].y;
398         }
399         (*pt).x += (int) (offset.x + .5);
400         (*pt).y += (int) (offset.y + .5);
401 }
402
403
404 /* Mop up dynamic data for one screen. */
405 static void
406 free_penrose(tiling_c * tp)
407 {
408         register fringe_node_c *fp1, *fp2;
409         register forced_node_c *lp1, *lp2;
410
411         if (tp->fringe.nodes == NULL)
412                 return;
413         fp1 = tp->fringe.nodes;
414         do {
415                 fp2 = fp1;
416                 fp1 = fp1->next;
417                 (void) free((void *) fp2);
418         } while (fp1 != tp->fringe.nodes);
419         tp->fringe.nodes = (fringe_node_c *) NULL;
420         for (lp1 = tp->forced.first; lp1 != 0;) {
421                 lp2 = lp1;
422                 lp1 = lp1->next;
423                 (void) free((void *) lp2);
424         }
425         tp->forced.first = 0;
426 }
427
428
429 /* Called to init the mode. */
430 void
431 init_penrose(ModeInfo * mi)
432 {
433         tiling_c   *tp;
434         fringe_node_c *fp;
435         int         i, size;
436
437         if (tilings == NULL) {
438                 if ((tilings = (tiling_c *) calloc(MI_NUM_SCREENS(mi),
439                                                  sizeof (tiling_c))) == NULL)
440                         return;
441         }
442         tp = &tilings[MI_SCREEN(mi)];
443
444         if (MI_IS_FULLRANDOM(mi))
445                 tp->ammann = (Bool) (LRAND() & 1);
446         else
447                 tp->ammann = ammann;
448         tp->done = False;
449         tp->busyLoop = 0;
450         tp->failures = 0;
451         tp->width = MI_WIDTH(mi);
452         tp->height = MI_HEIGHT(mi);
453         if (MI_NPIXELS(mi) > 2) {
454                 tp->thick_color = NRAND(MI_NPIXELS(mi));
455                 /* Insure good contrast */
456                 tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color +
457                                   MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi);
458         }
459         size = MI_SIZE(mi);
460         if (size < -MINSIZE)
461                 tp->edge_length = NRAND(MIN(-size, MAX(MINSIZE,
462                    MIN(tp->width, tp->height) / 2)) - MINSIZE + 1) + MINSIZE;
463         else if (size < MINSIZE) {
464                 if (!size)
465                         tp->edge_length = MAX(MINSIZE, MIN(tp->width, tp->height) / 2);
466                 else
467                         tp->edge_length = MINSIZE;
468         } else
469                 tp->edge_length = MIN(size, MAX(MINSIZE,
470                                             MIN(tp->width, tp->height) / 2));
471         tp->origin.x = (tp->width / 2 + NRAND(tp->width)) / 2;
472         tp->origin.y = (tp->height / 2 + NRAND(tp->height)) / 2;
473         tp->fringe.n_nodes = 2;
474         if (tp->fringe.nodes != NULL)
475                 free_penrose(tp);
476         if (tp->fringe.nodes != NULL || tp->forced.first != 0) {
477                 if (MI_IS_VERBOSE(mi)) {
478                         (void) fprintf(stderr, "Weirdness in init_penrose()\n");
479                         (void) fprintf(stderr, "tp->fringe.nodes = NULL && tp->forced.first = 0\n");
480                 }
481                 free_penrose(tp);       /* Try again */
482                 tp->done = True;
483         }
484         tp->forced.n_nodes = tp->forced.n_visible = 0;
485         if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) {
486                 free_penrose(tp);
487                 return;
488         }
489         if (fp == 0) {
490                 if (MI_IS_VERBOSE(mi)) {
491                         (void) fprintf(stderr, "Weirdness in init_penrose()\n");
492                         (void) fprintf(stderr, "fp = 0\n");
493                 }
494                 if ((fp = tp->fringe.nodes = ALLOC_NODE(fringe_node_c)) == NULL) {
495                         free_penrose(tp);
496                         return;
497                 }
498                 tp->done = True;
499         }
500         /* First vertex. */
501         fp->rule_mask = (1 << N_VERTEX_RULES) - 1;
502         fp->list_ptr = 0;
503         if  ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) {
504                 free_penrose(tp);
505                 return;
506         }
507         if (fp->next == 0) {
508                 if (MI_IS_VERBOSE(mi)) {
509                         (void) fprintf(stderr, "Weirdness in init_penrose()\n");
510                         (void) fprintf(stderr, "fp->next = 0\n");
511                 }
512                 if ((fp->prev = fp->next = ALLOC_NODE(fringe_node_c)) == NULL) {
513                         free_penrose(tp);
514                         return;
515                 }
516                 tp->done = True;
517         }
518         fp->n_tiles = 0;
519         fp->loc = tp->origin;
520         fp->off_screen = False;
521         for (i = 0; i < 5; i++)
522                 fp->fived[i] = 0;
523
524         /* Second vertex. */
525         *(fp->next) = *fp;
526         fp->next->prev = fp->next->next = fp;
527         fp = fp->next;
528         i = NRAND(5);
529         fp->fived[i] = 2 * NRAND(2) - 1;
530         fived_to_loc(fp->fived, tp, &(fp->loc));
531         /* That's it!  We have created our first edge. */
532 }
533
534 /*-
535  * This attempts to match the configuration of vertex with the vertex
536  * rules.   The return value is a total match count.  If matches is
537  * non-null, it will be used to store information about the matches
538  * and must be large enough to contain it.  To play it absolutely
539  * safe, allocate room for MAX_TILES_PER_VERTEX * N_VERTEX_RULES
540  * entries when searching all matches.   The rule mask of vertex will
541  * be applied and rules masked out will not be searched.  Only strict
542  * subsequences match.  If first_only is true, the search stops when
543  * the first match is found.  Otherwise all matches will be found and
544  * the rule_mask of vertex will be updated, which also happens in
545  * single-match mode if no match is found.
546  */
547 static int
548 match_rules(fringe_node_c * vertex, rule_match_c * matches, int first_only)
549 {
550         /* I will assume that I can fit all the relevant bits in vertex->tiles
551            into one unsigned long.  With 3 bits per element and at most 7
552            elements this means 21 bits, which should leave plenty of room.
553            After packing the bits the rest is just integer comparisons and
554            some bit shuffling.  This is essentially Rabin-Karp without
555            congruence arithmetic. */
556         register int i, j;
557         int         hits = 0, good_rules[N_VERTEX_RULES], n_good = 0;
558         unsigned long
559                     vertex_hash = 0, lower_bits_mask = ~(VT_TOTAL_MASK << VT_BITS * (vertex->n_tiles - 1));
560         unsigned    new_rule_mask = 0;
561
562         for (i = 0; i < N_VERTEX_RULES; i++)
563                 if (vertex->n_tiles >= vertex_rules[i].n_tiles)
564                         vertex->rule_mask &= ~(1 << i);
565                 else if (vertex->rule_mask & 1 << i)
566                         good_rules[n_good++] = i;
567         for (i = 0; i < vertex->n_tiles; i++)
568                 vertex_hash |= (unsigned long) vertex->tiles[i] << (VT_BITS * i);
569
570         for (j = 0; j < n_good; j++) {
571                 unsigned long rule_hash = 0;
572                 vertex_rule_c *vr = vertex_rules + good_rules[j];
573
574                 for (i = 0; i < vertex->n_tiles; i++)
575                         rule_hash |= (unsigned long) vr->tiles[i] << (VT_BITS * i);
576                 if (rule_hash == vertex_hash) {
577                         if (matches != 0) {
578                                 matches[hits].rule = good_rules[j];
579                                 matches[hits].pos = 0;
580                         }
581                         hits++;
582                         if (first_only)
583                                 return hits;
584                         else
585                                 new_rule_mask |= 1 << good_rules[j];
586                 }
587                 for (i = vr->n_tiles - 1; i > 0; i--) {
588                         rule_hash = vr->tiles[i] | (rule_hash & lower_bits_mask) << VT_BITS;
589                         if (vertex_hash == rule_hash) {
590                                 if (matches != 0) {
591                                         matches[hits].rule = good_rules[j];
592                                         matches[hits].pos = i;
593                                 }
594                                 hits++;
595                                 if (first_only)
596                                         return hits;
597                                 else
598                                         new_rule_mask |= 1 << good_rules[j];
599                         }
600                 }
601         }
602         vertex->rule_mask = new_rule_mask;
603         return hits;
604 }
605
606
607 /*-
608  * find_completions finds the possible ways to add a tile to a vertex.
609  * The return values is the number of such possibilities.  You must
610  * first call match_rules to produce matches and n_matches.  sides
611  * specifies which side of the vertex to extend and can be S_LEFT or
612  * S_RIGHT.  If results is non-null, it should point to an array large
613  * enough to contain the results, which will be stored there.
614  * MAX_COMPL elements will always suffice.  If first_only is true we
615  * stop as soon as we find one possibility (NOT USED).
616  */
617 #define MAX_COMPL 2
618
619 static int
620 find_completions(fringe_node_c * vertex, rule_match_c * matches, int n_matches,
621                unsigned side, vertex_type_c * results /*, int first_only */ )
622 {
623         int         n_res = 0, cont;
624         register int i, j;
625         vertex_type_c buf[MAX_COMPL];
626
627         if (results == 0)
628                 results = buf;
629         if (n_matches <= 0)
630                 return 0;
631         for (i = 0; i < n_matches; i++) {
632                 vertex_rule_c *rule = vertex_rules + matches[i].rule;
633                 int         pos = (matches[i].pos
634                    + (side == S_RIGHT ? vertex->n_tiles : rule->n_tiles - 1))
635                 % rule->n_tiles;
636                 vertex_type_c vtype = rule->tiles[pos];
637
638                 cont = 1;
639                 for (j = 0; j < n_res; j++)
640                         if (vtype == results[j]) {
641                                 cont = 0;
642                                 break;
643                         }
644                 if (cont)
645                         results[n_res++] = vtype;
646         }
647         return n_res;
648 }
649
650
651 /*-
652  * Draw a tile on the display.  Vertices must be given in a
653  * counterclockwise order.  vtype is the vertex type of v1 (and thus
654  * also gives the tile type).
655  */
656 static void
657 draw_tile(fringe_node_c * v1, fringe_node_c * v2,
658           fringe_node_c * v3, fringe_node_c * v4,
659           vertex_type_c vtype, ModeInfo * mi)
660 {
661         Display    *display = MI_DISPLAY(mi);
662         Window      window = MI_WINDOW(mi);
663         GC          gc = MI_GC(mi);
664         tiling_c   *tp = &tilings[MI_SCREEN(mi)];
665         XPoint      pts[5];
666         vertex_type_c corner = vtype & VT_CORNER_MASK;
667
668         if (v1->off_screen && v2->off_screen && v3->off_screen && v4->off_screen)
669                 return;
670         pts[corner] = v1->loc;
671         pts[VT_RIGHT(corner)] = v2->loc;
672         pts[VT_FAR(corner)] = v3->loc;
673         pts[VT_LEFT(corner)] = v4->loc;
674         pts[4] = pts[0];
675         if (MI_NPIXELS(mi) > 2) {
676                 if ((vtype & VT_TYPE_MASK) == VT_THICK)
677                         XSetForeground(display, gc, MI_PIXEL(mi, tp->thick_color));
678                 else
679                         XSetForeground(display, gc, MI_PIXEL(mi, tp->thin_color));
680         } else
681                 XSetForeground(display, gc, MI_WHITE_PIXEL(mi));
682         XFillPolygon(display, window, gc, pts, 4, Convex, CoordModeOrigin);
683         XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
684         XDrawLines(display, window, gc, pts, 5, CoordModeOrigin);
685
686         if (tp->ammann) {
687                 /* Draw some Ammann lines for debugging purposes.  This will probably
688                    fail miserably on a b&w display. */
689
690                 if ((vtype & VT_TYPE_MASK) == VT_THICK) {
691                         static float r = .0;
692
693                         if (r == .0) {
694                                 float       pi10 = 2 * atan(1.) / 5;
695
696                                 r = 1 - sin(pi10) / (2 * sin(3 * pi10));
697                         }
698                         if (MI_NPIXELS(mi) > 2)
699                                 XSetForeground(display, gc, MI_PIXEL(mi, tp->thin_color));
700                         else {
701                                 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
702                                 XSetLineAttributes(display, gc, 1, LineOnOffDash, CapNotLast, JoinMiter);
703                         }
704                         XDrawLine(display, window, gc,
705                               (int) (r * pts[3].x + (1 - r) * pts[0].x + .5),
706                               (int) (r * pts[3].y + (1 - r) * pts[0].y + .5),
707                               (int) (r * pts[1].x + (1 - r) * pts[0].x + .5),
708                              (int) (r * pts[1].y + (1 - r) * pts[0].y + .5));
709                         if (MI_NPIXELS(mi) <= 2)
710                                 XSetLineAttributes(display, gc, 1, LineSolid, CapNotLast, JoinMiter);
711                 } else {
712                         if (MI_NPIXELS(mi) > 2)
713                                 XSetForeground(display, gc, MI_PIXEL(mi, tp->thick_color));
714                         else {
715                                 XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
716                                 XSetLineAttributes(display, gc, 1, LineOnOffDash, CapNotLast, JoinMiter);
717                         }
718                         XDrawLine(display, window, gc,
719                                   (int) ((pts[3].x + pts[2].x) / 2 + .5),
720                                   (int) ((pts[3].y + pts[2].y) / 2 + .5),
721                                   (int) ((pts[1].x + pts[2].x) / 2 + .5),
722                                   (int) ((pts[1].y + pts[2].y) / 2 + .5));
723                         if (MI_NPIXELS(mi) <= 2)
724                                 XSetLineAttributes(display, gc, 1, LineSolid, CapNotLast, JoinMiter);
725                 }
726         }
727 }
728
729 /*-
730  * Update the status of this vertex on the forced vertex queue.  If
731  * the vertex has become untileable set tp->done.  This is supposed
732  * to detect dislocations -- never call this routine with a completely
733  * tiled vertex.
734  *
735  * Check for untileable vertices in check_vertex and stop tiling as
736  * soon as one finds one.  I don't know if it is possible to run out
737  * of forced vertices while untileable vertices exist (or will
738  * cavities inevitably appear).  If this can happen, add_random_tile
739  * might get called with an untileable vertex, causing ( n <= 1).
740  * (This is what the tp->done checks for).
741  *
742  * A delayLoop celebrates the dislocation.
743  */
744 static void
745 check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp)
746 {
747         rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
748         int         n_hits = match_rules(vertex, hits, False);
749         unsigned    forced_sides = 0;
750
751         if (vertex->rule_mask == 0) {
752                 tp->done = True;
753                 if (MI_IS_VERBOSE(mi)) {
754                         (void) fprintf(stderr, "Dislocation occurred!\n");
755                 }
756                 tp->busyLoop = CELEBRATE;       /* Should be able to recover */
757         }
758         if (1 == find_completions(vertex, hits, n_hits, S_LEFT, 0 /*, False */ ))
759                 forced_sides |= S_LEFT;
760         if (1 == find_completions(vertex, hits, n_hits, S_RIGHT, 0 /*, False */ ))
761                 forced_sides |= S_RIGHT;
762         if (forced_sides == 0) {
763                 if (vertex->list_ptr != 0) {
764                         forced_node_c *node = *vertex->list_ptr;
765
766                         *vertex->list_ptr = node->next;
767                         if (node->next != 0)
768                                 node->next->vertex->list_ptr = vertex->list_ptr;
769                         (void) free((void *) node);
770                         tp->forced.n_nodes--;
771                         if (!vertex->off_screen)
772                                 tp->forced.n_visible--;
773                         vertex->list_ptr = 0;
774                 }
775         } else {
776                 forced_node_c *node;
777
778                 if (vertex->list_ptr == 0) {
779                         if ((node = ALLOC_NODE(forced_node_c)) == NULL)
780                                 return;
781                         node->vertex = vertex;
782                         node->next = tp->forced.first;
783                         if (tp->forced.first != 0)
784                                 tp->forced.first->vertex->list_ptr = &(node->next);
785                         tp->forced.first = node;
786                         vertex->list_ptr = &(tp->forced.first);
787                         tp->forced.n_nodes++;
788                         if (!vertex->off_screen)
789                                 tp->forced.n_visible++;
790                 } else
791                         node = *vertex->list_ptr;
792                 node->forced_sides = forced_sides;
793         }
794 }
795
796
797 /*-
798  * Delete this vertex.  If the vertex is a member of the forced vertex queue,
799  * also remove that entry.  We assume that the vertex is no longer
800  * connected to the fringe.  Note that tp->fringe.nodes must not point to
801  * the vertex being deleted.
802  */
803 static void
804 delete_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp)
805 {
806         if (tp->fringe.nodes == vertex) {
807                 tp->done = True;
808                 if (MI_IS_VERBOSE(mi)) {
809                         (void) fprintf(stderr, "Weirdness in delete_penrose()\n");
810                         (void) fprintf(stderr, "tp->fringe.nodes == vertex\n");
811                 }
812                 tp->busyLoop = CELEBRATE;
813         }
814         if (vertex->list_ptr != 0) {
815                 forced_node_c *node = *vertex->list_ptr;
816
817                 *vertex->list_ptr = node->next;
818                 if (node->next != 0)
819                         node->next->vertex->list_ptr = vertex->list_ptr;
820                 (void) free((void *) node);
821                 tp->forced.n_nodes--;
822                 if (!vertex->off_screen)
823                         tp->forced.n_visible--;
824         }
825         if (!vertex->off_screen)
826                 tp->fringe.n_nodes--;
827         (void) free((void *) vertex);
828 }
829
830
831 /*-
832  * Check whether the addition of a tile of type vtype would completely fill
833  * the space available at vertex.
834  */
835 static int
836 fills_vertex(ModeInfo * mi, vertex_type_c vtype, fringe_node_c * vertex)
837 {
838         return
839                 (vertex_dir(mi, vertex, S_LEFT) - vertex_dir(mi, vertex, S_RIGHT)
840                  - vtype_angle(vtype)) % 10 == 0;
841 }
842
843
844 /*-
845  * If you were to add a tile of type vtype to a specified side of
846  * vertex, fringe_changes tells you which other vertices it would
847  * attach to.  The addresses of these vertices will be stored in the
848  * last three arguments.  Null is stored if the corresponding vertex
849  * would need to be allocated.
850  *
851  * The function also analyzes which vertices would be swallowed by the tiling
852  * and thus cut off from the fringe.  The result is returned as a bit pattern.
853  */
854 #define FC_BAG 1                /* Total enclosure.  Should never occur. */
855 #define FC_NEW_RIGHT 2
856 #define FC_NEW_FAR 4
857 #define FC_NEW_LEFT 8
858 #define FC_NEW_MASK 0xe
859 #define FC_CUT_THIS 0x10
860 #define FC_CUT_RIGHT 0x20
861 #define FC_CUT_FAR 0x40
862 #define FC_CUT_LEFT 0x80
863 #define FC_CUT_MASK 0xf0
864 #define FC_TOTAL_MASK 0xff
865
866 static unsigned
867 fringe_changes(ModeInfo * mi, fringe_node_c * vertex,
868                unsigned side, vertex_type_c vtype,
869                fringe_node_c ** right, fringe_node_c ** far,
870                fringe_node_c ** left)
871 {
872         fringe_node_c *v, *f = (fringe_node_c *) NULL;
873         unsigned    result = FC_NEW_FAR;        /* We clear this later if necessary. */
874
875         if (far)
876                 *far = 0;
877         if (fills_vertex(mi, vtype, vertex)) {
878                 result |= FC_CUT_THIS;
879         } else if (side == S_LEFT) {
880                 result |= FC_NEW_RIGHT;
881                 if (right)
882                         *right = 0;
883         } else {
884                 result |= FC_NEW_LEFT;
885                 if (left)
886                         *left = 0;
887         }
888
889         if (!(result & FC_NEW_LEFT)) {
890                 v = vertex->next;
891                 if (left)
892                         *left = v;
893                 if (fills_vertex(mi, VT_LEFT(vtype), v)) {
894                         result = (result & ~FC_NEW_FAR) | FC_CUT_LEFT;
895                         f = v->next;
896                         if (far)
897                                 *far = f;
898                 }
899         }
900         if (!(result & FC_NEW_RIGHT)) {
901                 v = vertex->prev;
902                 if (right)
903                         *right = v;
904                 if (fills_vertex(mi, VT_RIGHT(vtype), v)) {
905                         result = (result & ~FC_NEW_FAR) | FC_CUT_RIGHT;
906                         f = v->prev;
907                         if (far)
908                                 *far = f;
909                 }
910         }
911         if (!(result & FC_NEW_FAR)
912             && fills_vertex(mi, VT_FAR(vtype), f)) {
913                 result |= FC_CUT_FAR;
914                 result &= (~FC_NEW_LEFT & ~FC_NEW_RIGHT);
915                 if (right && (result & FC_CUT_LEFT))
916                         *right = f->next;
917                 if (left && (result & FC_CUT_RIGHT))
918                         *left = f->prev;
919         }
920         if (((result & FC_CUT_LEFT) && (result & FC_CUT_RIGHT))
921             || ((result & FC_CUT_THIS) && (result & FC_CUT_FAR)))
922                 result |= FC_BAG;
923         return result;
924 }
925
926
927 /* A couple of lesser helper functions for add_tile. */
928 static void
929 add_vtype(fringe_node_c * vertex, unsigned side, vertex_type_c vtype)
930 {
931         if (side == S_RIGHT)
932                 vertex->tiles[vertex->n_tiles++] = vtype;
933         else {
934                 register int i;
935
936                 for (i = vertex->n_tiles; i > 0; i--)
937                         vertex->tiles[i] = vertex->tiles[i - 1];
938                 vertex->tiles[0] = vtype;
939                 vertex->n_tiles++;
940         }
941 }
942
943 static fringe_node_c *
944 alloc_vertex(ModeInfo * mi, angle_c dir, fringe_node_c * from, tiling_c * tp)
945 {
946         fringe_node_c *v;
947
948         if ((v = ALLOC_NODE(fringe_node_c)) == NULL) {
949                 tp->done = True;
950                 if (MI_IS_VERBOSE(mi)) {
951                         (void) fprintf(stderr, "No memory in alloc_vertex()\n");
952                 }
953                 tp->busyLoop = CELEBRATE;
954                 return v;
955         }
956         *v = *from;
957         add_unit_vec(dir, v->fived);
958         fived_to_loc(v->fived, tp, &(v->loc));
959         if (v->loc.x < 0 || v->loc.y < 0
960             || v->loc.x >= tp->width || v->loc.y >= tp->height) {
961                 v->off_screen = True;
962                 if (v->loc.x < -tp->width || v->loc.y < -tp->height
963                   || v->loc.x >= 2 * tp->width || v->loc.y >= 2 * tp->height)
964                         tp->done = True;
965         } else {
966                 v->off_screen = False;
967                 tp->fringe.n_nodes++;
968         }
969         v->n_tiles = 0;
970         v->rule_mask = (1 << N_VERTEX_RULES) - 1;
971         v->list_ptr = 0;
972         return v;
973 }
974
975 /*-
976  * Add a tile described by vtype to the side of vertex.  This must be
977  * allowed by the rules -- we do not check it here.  New vertices are
978  * allocated as necessary.  The fringe and the forced vertex pool are updated.
979  * The new tile is drawn on the display.
980  *
981  * One thing we do check here is whether the new tile causes an untiled
982  * area to become enclosed by the tiling.  If this would happen, the tile
983  * is not added.  The return value is true iff a tile was added.
984  */
985 static int
986 add_tile(ModeInfo * mi,
987          fringe_node_c * vertex, unsigned side, vertex_type_c vtype)
988 {
989         tiling_c   *tp = &tilings[MI_SCREEN(mi)];
990
991         fringe_node_c
992                 *left = (fringe_node_c *) NULL,
993                 *right = (fringe_node_c *) NULL,
994                 *far = (fringe_node_c *) NULL,
995                 *node;
996         unsigned    fc = fringe_changes(mi, vertex, side, vtype, &right, &far, &left);
997
998         vertex_type_c
999                 ltype = VT_LEFT(vtype),
1000                 rtype = VT_RIGHT(vtype),
1001                 ftype = VT_FAR(vtype);
1002
1003         /* By our conventions vertex->next lies to the left of vertex and
1004            vertex->prev to the right. */
1005
1006         /* This should never occur. */
1007         if (fc & FC_BAG) {
1008                 tp->done = True;
1009                 if (MI_IS_VERBOSE(mi)) {
1010                         (void) fprintf(stderr, "Weirdness in add_tile()\n");
1011                         (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG);
1012                 }
1013         }
1014         if (side == S_LEFT) {
1015                 if (right == NULL)
1016                         if ((right = alloc_vertex(mi, vertex_dir(mi, vertex, S_LEFT) -
1017                                         vtype_angle(vtype), vertex, tp)) == NULL)
1018                                 return False;
1019                 if (far == NULL)
1020                         if ((far = alloc_vertex(mi, vertex_dir(mi, left, S_RIGHT) +
1021                                         vtype_angle(ltype), left, tp)) == NULL)
1022                                 return False;
1023         } else {
1024                 if (left == NULL)
1025                         if ((left = alloc_vertex(mi, vertex_dir(mi, vertex, S_RIGHT) +
1026                                         vtype_angle(vtype), vertex, tp)) == NULL)
1027                                 return False;
1028                 if (far == NULL)
1029                         if ((far = alloc_vertex(mi, vertex_dir(mi, right, S_LEFT) -
1030                                         vtype_angle(rtype), right, tp)) == NULL)
1031                                 return False;
1032         }
1033
1034         /* Having allocated the new vertices, but before joining them with
1035            the rest of the fringe, check if vertices with same coordinates
1036            already exist.  If any such are found, give up. */
1037         node = tp->fringe.nodes;
1038         do {
1039                 if (((fc & FC_NEW_LEFT) && fived_equal(node->fived, left->fived))
1040                     || ((fc & FC_NEW_RIGHT) && fived_equal(node->fived, right->fived))
1041                     || ((fc & FC_NEW_FAR) && fived_equal(node->fived, far->fived))) {
1042                         /* Better luck next time. */
1043                         if (fc & FC_NEW_LEFT)
1044                                 delete_vertex(mi, left, tp);
1045                         if (fc & FC_NEW_RIGHT)
1046                                 delete_vertex(mi, right, tp);
1047                         if (fc & FC_NEW_FAR)
1048                                 delete_vertex(mi, far, tp);
1049                         return False;
1050                 }
1051                 node = node->next;
1052         } while (node != tp->fringe.nodes);
1053
1054         /* Rechain. */
1055         if (!(fc & FC_CUT_THIS)) {
1056                 if (side == S_LEFT) {
1057                         vertex->next = right;
1058                         right->prev = vertex;
1059                 } else {
1060                         vertex->prev = left;
1061                         left->next = vertex;
1062                 }
1063         }
1064         if (!(fc & FC_CUT_FAR)) {
1065                 if (!(fc & FC_CUT_LEFT)) {
1066                         far->next = left;
1067                         left->prev = far;
1068                 }
1069                 if (!(fc & FC_CUT_RIGHT)) {
1070                         far->prev = right;
1071                         right->next = far;
1072                 }
1073         }
1074         draw_tile(vertex, right, far, left, vtype, mi);
1075
1076         /* Delete vertices that are no longer on the fringe.  Check the others. */
1077         if (fc & FC_CUT_THIS) {
1078                 tp->fringe.nodes = far;
1079                 delete_vertex(mi, vertex, tp);
1080         } else {
1081                 add_vtype(vertex, side, vtype);
1082                 check_vertex(mi, vertex, tp);
1083                 tp->fringe.nodes = vertex;
1084         }
1085         if (fc & FC_CUT_FAR)
1086                 delete_vertex(mi, far, tp);
1087         else {
1088                 add_vtype(far, fc & FC_CUT_RIGHT ? S_LEFT : S_RIGHT, ftype);
1089                 check_vertex(mi, far, tp);
1090         }
1091         if (fc & FC_CUT_LEFT)
1092                 delete_vertex(mi, left, tp);
1093         else {
1094                 add_vtype(left, fc & FC_CUT_FAR ? S_LEFT : S_RIGHT, ltype);
1095                 check_vertex(mi, left, tp);
1096         }
1097         if (fc & FC_CUT_RIGHT)
1098                 delete_vertex(mi, right, tp);
1099         else {
1100                 add_vtype(right, fc & FC_CUT_FAR ? S_RIGHT : S_LEFT, rtype);
1101                 check_vertex(mi, right, tp);
1102         }
1103         return True;
1104 }
1105
1106
1107 /*-
1108  * Add a forced tile to a given forced vertex.  Basically an easy job,
1109  * since we know what to add.  But it might fail if adding the tile
1110  * would cause some untiled area to become enclosed.  There is also another
1111  * more exotic culprit: we might have a dislocation.  Fortunately, they
1112  * are very rare (the PRL article reported that perfect tilings of over
1113  * 2^50 tiles had been generated).  There is a version of the algorithm
1114  * that doesn't produce dislocations, but it's a lot hairier than the
1115  * simpler version I used.
1116  */
1117 static int
1118 add_forced_tile(ModeInfo * mi, forced_node_c * node)
1119 {
1120         tiling_c   *tp = &tilings[MI_SCREEN(mi)];
1121         unsigned    side;
1122         vertex_type_c vtype;
1123         rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
1124         int         n;
1125
1126         if (node->forced_sides == (S_LEFT | S_RIGHT))
1127                 side = NRAND(2) ? S_LEFT : S_RIGHT;
1128         else
1129                 side = node->forced_sides;
1130         n = match_rules(node->vertex, hits, True);
1131         n = find_completions(node->vertex, hits, n, side, &vtype /*, True */ );
1132         if (n <= 0) {
1133                 tp->done = True;
1134                 if (MI_IS_VERBOSE(mi)) {
1135                         (void) fprintf(stderr, "Weirdness in add_forced_tile()\n");
1136                         (void) fprintf(stderr, "n = %d\n", n);
1137                 }
1138         }
1139         return add_tile(mi, node->vertex, side, vtype);
1140 }
1141
1142
1143 /*-
1144  * Whether the addition of a tile of vtype on the given side of vertex
1145  * would conform to the rules.  The efficient way to do this would be
1146  * to add the new tile and then use the same type of search as in
1147  * match_rules.  However, this function is not a performance
1148  * bottleneck (only needed for random tile additions, which are
1149  * relatively infrequent), so I will settle for a simpler implementation.
1150  */
1151 static int
1152 legal_move(fringe_node_c * vertex, unsigned side, vertex_type_c vtype)
1153 {
1154         rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
1155         vertex_type_c legal_vt[MAX_COMPL];
1156         int         n_hits, n_legal, i;
1157
1158         n_hits = match_rules(vertex, hits, False);
1159         n_legal = find_completions(vertex, hits, n_hits, side, legal_vt /*, False */ );
1160         for (i = 0; i < n_legal; i++)
1161                 if (legal_vt[i] == vtype)
1162                         return True;
1163         return False;
1164 }
1165
1166
1167 /*-
1168  * Add a randomly chosen tile to a given vertex.  This requires more checking
1169  * as we must make sure the new tile conforms to the vertex rules at every
1170  * vertex it touches. */
1171 static void
1172 add_random_tile(fringe_node_c * vertex, ModeInfo * mi)
1173 {
1174         fringe_node_c *right, *left, *far;
1175         int         i, j, n, n_hits, n_good;
1176         unsigned    side, fc, no_good, s;
1177         vertex_type_c vtypes[MAX_COMPL];
1178         rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES];
1179         tiling_c   *tp = &tilings[MI_SCREEN(mi)];
1180
1181         if (MI_NPIXELS(mi) > 2) {
1182                 tp->thick_color = NRAND(MI_NPIXELS(mi));
1183                 /* Insure good contrast */
1184                 tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color +
1185                                   MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi);
1186         } else
1187                 tp->thick_color = tp->thin_color = MI_WHITE_PIXEL(mi);
1188         n_hits = match_rules(vertex, hits, False);
1189         side = NRAND(2) ? S_LEFT : S_RIGHT;
1190         n = find_completions(vertex, hits, n_hits, side, vtypes /*, False */ );
1191         /* One answer would mean a forced tile. */
1192         if (n <= 0) {
1193                 tp->done = True;
1194                 if (MI_IS_VERBOSE(mi)) {
1195                         (void) fprintf(stderr, "Weirdness in add_random_tile()\n");
1196                         (void) fprintf(stderr, "n = %d\n", n);
1197                 }
1198         }
1199         no_good = 0;
1200         n_good = n;
1201         for (i = 0; i < n; i++) {
1202                 fc = fringe_changes(mi, vertex, side, vtypes[i], &right, &far, &left);
1203                 if (fc & FC_BAG) {
1204                         tp->done = True;
1205                         if (MI_IS_VERBOSE(mi)) {
1206                                 (void) fprintf(stderr, "Weirdness in add_random_tile()\n");
1207                                 (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG);
1208                         }
1209                 }
1210                 if (right) {
1211                         s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_LEFT)) ? S_RIGHT : S_LEFT);
1212                         if (!legal_move(right, s, VT_RIGHT(vtypes[i]))) {
1213                                 no_good |= (1 << i);
1214                                 n_good--;
1215                                 continue;
1216                         }
1217                 }
1218                 if (left) {
1219                         s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_RIGHT)) ? S_LEFT : S_RIGHT);
1220                         if (!legal_move(left, s, VT_LEFT(vtypes[i]))) {
1221                                 no_good |= (1 << i);
1222                                 n_good--;
1223                                 continue;
1224                         }
1225                 }
1226                 if (far) {
1227                         s = ((fc & FC_CUT_LEFT) ? S_RIGHT : S_LEFT);
1228                         if (!legal_move(far, s, VT_FAR(vtypes[i]))) {
1229                                 no_good |= (1 << i);
1230                                 n_good--;
1231                         }
1232                 }
1233         }
1234         if (n_good <= 0) {
1235                 tp->done = True;
1236                 if (MI_IS_VERBOSE(mi)) {
1237                         (void) fprintf(stderr, "Weirdness in add_random_tile()\n");
1238                         (void) fprintf(stderr, "n_good = %d\n", n_good);
1239                 }
1240         }
1241         n = NRAND(n_good);
1242         for (i = j = 0; i <= n; i++, j++)
1243                 while (no_good & (1 << j))
1244                         j++;
1245
1246         if (!add_tile(mi, vertex, side, vtypes[j - 1])) {
1247                 tp->done = True;
1248                 if (MI_IS_VERBOSE(mi)) {
1249                         (void) fprintf(stderr, "Weirdness in add_random_tile()\n");
1250                 }
1251                 free_penrose(tp);
1252         }
1253 }
1254
1255 /* One step of the growth algorithm. */
1256 void
1257 draw_penrose(ModeInfo * mi)
1258 {
1259         int         i = 0, n;
1260         forced_node_c *p;
1261         tiling_c   *tp;
1262
1263         if (tilings == NULL)
1264                 return;
1265         tp = &tilings[MI_SCREEN(mi)];
1266         if (tp->fringe.nodes == NULL)
1267                 return;
1268
1269         MI_IS_DRAWN(mi) = True;
1270         p = tp->forced.first;
1271         if (tp->busyLoop > 0) {
1272                 tp->busyLoop--;
1273                 return;
1274         }
1275         if (tp->done || tp->failures >= 100) {
1276                 init_penrose(mi);
1277                 return;
1278         }
1279         /* Check for the initial "2-gon". */
1280         if (tp->fringe.nodes->prev == tp->fringe.nodes->next) {
1281                 vertex_type_c vtype = (unsigned char) (VT_TOTAL_MASK & LRAND());
1282
1283                 MI_CLEARWINDOW(mi);
1284
1285                 if (!add_tile(mi, tp->fringe.nodes, S_LEFT, vtype))
1286                         free_penrose(tp);
1287                 return;
1288         }
1289         /* No visible nodes left. */
1290         if (tp->fringe.n_nodes == 0) {
1291                 tp->done = True;
1292                 tp->busyLoop = COMPLETION;      /* Just finished drawing */
1293                 return;
1294         }
1295         if (tp->forced.n_visible > 0 && tp->failures < 10) {
1296                 n = NRAND(tp->forced.n_visible);
1297                 for (;;) {
1298                         while (p->vertex->off_screen)
1299                                 p = p->next;
1300                         if (i++ < n)
1301                                 p = p->next;
1302                         else
1303                                 break;
1304                 }
1305         } else if (tp->forced.n_nodes > 0) {
1306                 n = NRAND(tp->forced.n_nodes);
1307                 while (i++ < n)
1308                         p = p->next;
1309         } else {
1310                 fringe_node_c *fringe_p = tp->fringe.nodes;
1311
1312                 n = NRAND(tp->fringe.n_nodes);
1313                 i = 0;
1314                 for (; i <= n; i++)
1315                         do {
1316                                 fringe_p = fringe_p->next;
1317                         } while (fringe_p->off_screen);
1318                 add_random_tile(fringe_p, mi);
1319                 tp->failures = 0;
1320                 return;
1321         }
1322         if (add_forced_tile(mi, p))
1323                 tp->failures = 0;
1324         else
1325                 tp->failures++;
1326 }
1327
1328
1329 /* Total clean-up. */
1330 void
1331 release_penrose(ModeInfo * mi)
1332 {
1333         if (tilings != NULL) {
1334                 int         screen;
1335
1336                 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
1337                         free_penrose(&tilings[screen]);
1338                 (void) free((void *) tilings);
1339                 tilings = (tiling_c *) NULL;
1340         }
1341 }
1342
1343 #endif /* MODE_penrose */