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