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