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