ncurses 6.2 - patch 20210508
[ncurses.git] / test / xmas.c
1 /******************************************************************************/
2 /* asciixmas                                                                  */
3 /* December 1989             Larry Bartz           Indianapolis, IN           */
4 /*                                                                            */
5 /*                                                                            */
6 /* I'm dreaming of an ascii character-based monochrome Christmas,             */
7 /* Just like the one's I used to know!                                        */
8 /* Via a full duplex communications channel,                                  */
9 /* At 9600 bits per second,                                                   */
10 /* Even though it's kinda slow.                                               */
11 /*                                                                            */
12 /* I'm dreaming of an ascii character-based monochrome Christmas,             */
13 /* With ev'ry C program I write!                                              */
14 /* May your screen be merry and bright!                                       */
15 /* And may all your Christmases be amber or green,                            */
16 /* (for reduced eyestrain and improved visibility)!                           */
17 /*                                                                            */
18 /*                                                                            */
19 /*                                                                            */
20 /*                                                                            */
21 /*                                                                            */
22 /* IMPLEMENTATION                                                             */
23 /*                                                                            */
24 /* Feel free to modify the defined string FROMWHO to reflect you, your        */
25 /* organization, your site, whatever.                                         */
26 /*                                                                            */
27 /* This really looks a lot better if you can turn off your cursor before      */
28 /* execution. I wanted to do that here but very few termcap entries or        */
29 /* terminfo definitions have the appropriate string defined. If you know      */
30 /* the string(s) for the terminal(s) you use or which your site supports,     */
31 /* you could call asciixmas from within a shell in which you issue the        */
32 /* string to the terminal. The cursor is distracting but it doesn't really    */
33 /* ruin the show.                                                             */
34 /*                                                                            */
35 /* At our site, we invoke this for our users just after login and the         */
36 /* determination of terminal type.                                            */
37 /*                                                                            */
38 /*                                                                            */
39 /* PORTABILITY                                                                */
40 /*                                                                            */
41 /* I wrote this using only the very simplest curses functions so that it      */
42 /* might be the most portable. I was personally able to test on five          */
43 /* different cpu/UNIX combinations.                                           */
44 /*                                                                            */
45 /*                                                                            */
46 /* COMPILE                                                                    */
47 /*                                                                            */
48 /* usually this:                                                              */
49 /*                                                                            */
50 /* cc -O asciixmas.c -lcurses -o asciixmas -s                                 */
51 /*                                                                            */
52 /*                                                                            */
53 /* Zilog S8000 models 11, 21, 31, etc with ZEUS variant of SYSTEM III         */
54 /* maybe other SYSTEM III also:                                               */
55 /*                                                                            */
56 /* cc asciixmas.c -lcurses -ltermlib -o asciixmas -s                          */
57 /*                                                                            */
58 /* as above with optional "peephole optimizer" installed:                     */
59 /*                                                                            */
60 /* cc -O asciixmas.c -lcurses -ltermlib -o asciixmas -s                       */
61 /*                                                                            */
62 /*                                                                            */
63 /* Zilog S8000 models 32, 130 with WE32100 chip and SYS V, REL2               */
64 /* maybe 3B2 also?                                                            */
65 /*                                                                            */
66 /* cc -f -O -K sd asciixmas.c -lcurses -o asciixmas -s                        */
67 /*                                                                            */
68 /*                                                                            */
69 /* Pyramid, Sequent, any other "dual universe" types compile and execute      */
70 /* under either universe. The compile line for the ucb universe (as you       */
71 /* might expect) is the same as for SYS III UNIX:                             */
72 /*                                                                            */
73 /* cc -O asciixmas.c -lcurses -ltermlib -o asciixmas -s                       */
74 /*                                                                            */
75 /* The above compile will also hold true for other BSD systems. (I hope)      */
76 /*                                                                            */
77 /*                                                                            */
78 /*                                                                            */
79 /*                                                                            */
80 /* For the Scrooges out there among you who don't want this thing to loop     */
81 /* forever (or until the user hits a key), insert this into your compile      */
82 /* line just after "cc" :                                                     */
83 /*                                                                            */
84 /* -DNOLOOP                                                                   */
85 /*                                                                            */
86 /* like so:                                                                   */
87 /*                                                                            */
88 /* cc -DNOLOOP -O asciixmas.c -lcurses -o asciixmas -s                        */
89 /*                                                                            */
90 /*                                                                            */
91 /*                                                                            */
92 /******************************************************************************/
93
94 /*
95  * $Id: xmas.c,v 1.36 2021/03/27 22:40:53 tom Exp $
96  */
97 #include <test.priv.h>
98
99 #define FROMWHO "Mark Hessling - (M.Hessling@gu.edu.au)"
100
101 static int my_bg = COLOR_BLACK;
102 static int y_pos, x_pos;
103
104 static WINDOW *treescrn;
105 static WINDOW *treescrn2;
106 static WINDOW *treescrn3;
107 static WINDOW *treescrn4;
108 static WINDOW *treescrn5;
109 static WINDOW *treescrn6;
110 static WINDOW *treescrn7;
111 static WINDOW *treescrn8;
112 static WINDOW *dotdeer0;
113 static WINDOW *stardeer0;
114 static WINDOW *lildeer0;
115 static WINDOW *lildeer1;
116 static WINDOW *lildeer2;
117 static WINDOW *lildeer3;
118 static WINDOW *middeer0;
119 static WINDOW *middeer1;
120 static WINDOW *middeer2;
121 static WINDOW *middeer3;
122 static WINDOW *bigdeer0;
123 static WINDOW *bigdeer1;
124 static WINDOW *bigdeer2;
125 static WINDOW *bigdeer3;
126 static WINDOW *bigdeer4;
127 static WINDOW *lookdeer0;
128 static WINDOW *lookdeer1;
129 static WINDOW *lookdeer2;
130 static WINDOW *lookdeer3;
131 static WINDOW *lookdeer4;
132 static WINDOW *w_holiday;
133 static WINDOW *w_del_msg;
134 static bool *my_pairs;
135
136 static GCC_NORETURN void done(int sig);
137
138 static void
139 set_color(WINDOW *win, chtype color)
140 {
141     if (has_colors()) {
142         int n = (int) (color + 1);
143         if (my_pairs == 0)
144             my_pairs = typeCalloc(bool, (size_t) (COLORS + 1));
145         if (!my_pairs[n]) {
146             init_pair((short) n, (short) color, (short) my_bg);
147             my_pairs[n] = TRUE;
148         }
149         wattroff(win, A_COLOR);
150         wattron(win, COLOR_PAIR(n));
151     }
152 }
153
154 static void
155 unset_color(WINDOW *win)
156 {
157     if (has_colors())
158         (void) wattrset(win, COLOR_PAIR(0));
159 }
160
161 static void
162 look_out(int msecs)
163 {
164     napms(msecs);
165     if (getch() != ERR) {
166         beep();
167         done(0);
168     }
169 }
170
171 static int
172 boxit(void)
173 {
174     int x = 0;
175
176     while (x < 20) {
177         MvAddCh(x, 7, '|');
178         ++x;
179     }
180
181     x = 8;
182
183     while (x < 80) {
184         MvAddCh(19, x, '_');
185         ++x;
186     }
187
188     x = 0;
189
190     while (x < 80) {
191         MvAddCh(22, x, '_');
192         ++x;
193     }
194
195     return (0);
196 }
197
198 static int
199 seas(void)
200 {
201     MvAddCh(4, 1, 'S');
202     MvAddCh(6, 1, 'E');
203     MvAddCh(8, 1, 'A');
204     MvAddCh(10, 1, 'S');
205     MvAddCh(12, 1, 'O');
206     MvAddCh(14, 1, 'N');
207     MvAddCh(16, 1, '`');
208     MvAddCh(18, 1, 'S');
209
210     return (0);
211 }
212
213 static int
214 greet(void)
215 {
216     MvAddCh(3, 5, 'G');
217     MvAddCh(5, 5, 'R');
218     MvAddCh(7, 5, 'E');
219     MvAddCh(9, 5, 'E');
220     MvAddCh(11, 5, 'T');
221     MvAddCh(13, 5, 'I');
222     MvAddCh(15, 5, 'N');
223     MvAddCh(17, 5, 'G');
224     MvAddCh(19, 5, 'S');
225
226     return (0);
227 }
228
229 static int
230 fromwho(void)
231 {
232     MvAddStr(21, 13, FROMWHO);
233     return (0);
234 }
235
236 static int
237 tree(void)
238 {
239     set_color(treescrn, COLOR_GREEN);
240     MvWAddCh(treescrn, 1, 11, (chtype) '/');
241     MvWAddCh(treescrn, 2, 11, (chtype) '/');
242     MvWAddCh(treescrn, 3, 10, (chtype) '/');
243     MvWAddCh(treescrn, 4, 9, (chtype) '/');
244     MvWAddCh(treescrn, 5, 9, (chtype) '/');
245     MvWAddCh(treescrn, 6, 8, (chtype) '/');
246     MvWAddCh(treescrn, 7, 7, (chtype) '/');
247     MvWAddCh(treescrn, 8, 6, (chtype) '/');
248     MvWAddCh(treescrn, 9, 6, (chtype) '/');
249     MvWAddCh(treescrn, 10, 5, (chtype) '/');
250     MvWAddCh(treescrn, 11, 3, (chtype) '/');
251     MvWAddCh(treescrn, 12, 2, (chtype) '/');
252
253     MvWAddCh(treescrn, 1, 13, (chtype) '\\');
254     MvWAddCh(treescrn, 2, 13, (chtype) '\\');
255     MvWAddCh(treescrn, 3, 14, (chtype) '\\');
256     MvWAddCh(treescrn, 4, 15, (chtype) '\\');
257     MvWAddCh(treescrn, 5, 15, (chtype) '\\');
258     MvWAddCh(treescrn, 6, 16, (chtype) '\\');
259     MvWAddCh(treescrn, 7, 17, (chtype) '\\');
260     MvWAddCh(treescrn, 8, 18, (chtype) '\\');
261     MvWAddCh(treescrn, 9, 18, (chtype) '\\');
262     MvWAddCh(treescrn, 10, 19, (chtype) '\\');
263     MvWAddCh(treescrn, 11, 21, (chtype) '\\');
264     MvWAddCh(treescrn, 12, 22, (chtype) '\\');
265
266     MvWAddCh(treescrn, 4, 10, (chtype) '_');
267     MvWAddCh(treescrn, 4, 14, (chtype) '_');
268     MvWAddCh(treescrn, 8, 7, (chtype) '_');
269     MvWAddCh(treescrn, 8, 17, (chtype) '_');
270
271     MvWAddStr(treescrn, 13, 0, "//////////// \\\\\\\\\\\\\\\\\\\\\\\\");
272
273     MvWAddStr(treescrn, 14, 11, "| |");
274     MvWAddStr(treescrn, 15, 11, "|_|");
275
276     unset_color(treescrn);
277     wrefresh(treescrn);
278     wrefresh(w_del_msg);
279
280     return (0);
281 }
282
283 static int
284 balls(void)
285 {
286     overlay(treescrn, treescrn2);
287
288     set_color(treescrn2, COLOR_BLUE);
289     MvWAddCh(treescrn2, 3, 9, (chtype) '@');
290     MvWAddCh(treescrn2, 3, 15, (chtype) '@');
291     MvWAddCh(treescrn2, 4, 8, (chtype) '@');
292     MvWAddCh(treescrn2, 4, 16, (chtype) '@');
293     MvWAddCh(treescrn2, 5, 7, (chtype) '@');
294     MvWAddCh(treescrn2, 5, 17, (chtype) '@');
295     MvWAddCh(treescrn2, 7, 6, (chtype) '@');
296     MvWAddCh(treescrn2, 7, 18, (chtype) '@');
297     MvWAddCh(treescrn2, 8, 5, (chtype) '@');
298     MvWAddCh(treescrn2, 8, 19, (chtype) '@');
299     MvWAddCh(treescrn2, 10, 4, (chtype) '@');
300     MvWAddCh(treescrn2, 10, 20, (chtype) '@');
301     MvWAddCh(treescrn2, 11, 2, (chtype) '@');
302     MvWAddCh(treescrn2, 11, 22, (chtype) '@');
303     MvWAddCh(treescrn2, 12, 1, (chtype) '@');
304     MvWAddCh(treescrn2, 12, 23, (chtype) '@');
305
306     unset_color(treescrn2);
307     wrefresh(treescrn2);
308     wrefresh(w_del_msg);
309     return (0);
310 }
311
312 static int
313 star(void)
314 {
315     (void) wattrset(treescrn2, A_BOLD | A_BLINK);
316     set_color(treescrn2, COLOR_YELLOW);
317
318     MvWAddCh(treescrn2, 0, 12, (chtype) '*');
319     (void) wstandend(treescrn2);
320
321     unset_color(treescrn2);
322     wrefresh(treescrn2);
323     wrefresh(w_del_msg);
324     return (0);
325 }
326
327 static int
328 strng1(void)
329 {
330     (void) wattrset(treescrn2, A_BOLD | A_BLINK);
331     set_color(treescrn2, COLOR_WHITE);
332
333     MvWAddCh(treescrn2, 3, 13, (chtype) '\'');
334     MvWAddCh(treescrn2, 3, 12, (chtype) ':');
335     MvWAddCh(treescrn2, 3, 11, (chtype) '.');
336
337     wattroff(treescrn2, A_BOLD | A_BLINK);
338     unset_color(treescrn2);
339
340     wrefresh(treescrn2);
341     wrefresh(w_del_msg);
342     return (0);
343 }
344
345 static int
346 strng2(void)
347 {
348     (void) wattrset(treescrn2, A_BOLD | A_BLINK);
349     set_color(treescrn2, COLOR_WHITE);
350
351     MvWAddCh(treescrn2, 5, 14, (chtype) '\'');
352     MvWAddCh(treescrn2, 5, 13, (chtype) ':');
353     MvWAddCh(treescrn2, 5, 12, (chtype) '.');
354     MvWAddCh(treescrn2, 5, 11, (chtype) ',');
355     MvWAddCh(treescrn2, 6, 10, (chtype) '\'');
356     MvWAddCh(treescrn2, 6, 9, (chtype) ':');
357
358     wattroff(treescrn2, A_BOLD | A_BLINK);
359     unset_color(treescrn2);
360
361     wrefresh(treescrn2);
362     wrefresh(w_del_msg);
363     return (0);
364 }
365
366 static int
367 strng3(void)
368 {
369     (void) wattrset(treescrn2, A_BOLD | A_BLINK);
370     set_color(treescrn2, COLOR_WHITE);
371
372     MvWAddCh(treescrn2, 7, 16, (chtype) '\'');
373     MvWAddCh(treescrn2, 7, 15, (chtype) ':');
374     MvWAddCh(treescrn2, 7, 14, (chtype) '.');
375     MvWAddCh(treescrn2, 7, 13, (chtype) ',');
376     MvWAddCh(treescrn2, 8, 12, (chtype) '\'');
377     MvWAddCh(treescrn2, 8, 11, (chtype) ':');
378     MvWAddCh(treescrn2, 8, 10, (chtype) '.');
379     MvWAddCh(treescrn2, 8, 9, (chtype) ',');
380
381     wattroff(treescrn2, A_BOLD | A_BLINK);
382     unset_color(treescrn2);
383
384     wrefresh(treescrn2);
385     wrefresh(w_del_msg);
386     return (0);
387 }
388
389 static int
390 strng4(void)
391 {
392     (void) wattrset(treescrn2, A_BOLD | A_BLINK);
393     set_color(treescrn2, COLOR_WHITE);
394
395     MvWAddCh(treescrn2, 9, 17, (chtype) '\'');
396     MvWAddCh(treescrn2, 9, 16, (chtype) ':');
397     MvWAddCh(treescrn2, 9, 15, (chtype) '.');
398     MvWAddCh(treescrn2, 9, 14, (chtype) ',');
399     MvWAddCh(treescrn2, 10, 13, (chtype) '\'');
400     MvWAddCh(treescrn2, 10, 12, (chtype) ':');
401     MvWAddCh(treescrn2, 10, 11, (chtype) '.');
402     MvWAddCh(treescrn2, 10, 10, (chtype) ',');
403     MvWAddCh(treescrn2, 11, 9, (chtype) '\'');
404     MvWAddCh(treescrn2, 11, 8, (chtype) ':');
405     MvWAddCh(treescrn2, 11, 7, (chtype) '.');
406     MvWAddCh(treescrn2, 11, 6, (chtype) ',');
407     MvWAddCh(treescrn2, 12, 5, (chtype) '\'');
408
409     wattroff(treescrn2, A_BOLD | A_BLINK);
410     unset_color(treescrn2);
411
412     wrefresh(treescrn2);
413     wrefresh(w_del_msg);
414     return (0);
415 }
416
417 static int
418 strng5(void)
419 {
420     (void) wattrset(treescrn2, A_BOLD | A_BLINK);
421     set_color(treescrn2, COLOR_WHITE);
422
423     MvWAddCh(treescrn2, 11, 19, (chtype) '\'');
424     MvWAddCh(treescrn2, 11, 18, (chtype) ':');
425     MvWAddCh(treescrn2, 11, 17, (chtype) '.');
426     MvWAddCh(treescrn2, 11, 16, (chtype) ',');
427     MvWAddCh(treescrn2, 12, 15, (chtype) '\'');
428     MvWAddCh(treescrn2, 12, 14, (chtype) ':');
429     MvWAddCh(treescrn2, 12, 13, (chtype) '.');
430     MvWAddCh(treescrn2, 12, 12, (chtype) ',');
431
432     wattroff(treescrn2, A_BOLD | A_BLINK);
433     unset_color(treescrn2);
434
435     /* save a fully lit tree */
436     overlay(treescrn2, treescrn);
437
438     wrefresh(treescrn2);
439     wrefresh(w_del_msg);
440     return (0);
441 }
442
443 static int
444 blinkit(void)
445 {
446     static int cycle;
447
448     if (cycle > 4) {
449         cycle = 0;
450     }
451
452     touchwin(treescrn8);
453
454     switch (cycle) {
455     case 0:
456         overlay(treescrn3, treescrn8);
457         break;
458     case 1:
459         overlay(treescrn4, treescrn8);
460         break;
461     case 2:
462         overlay(treescrn5, treescrn8);
463         break;
464     case 3:
465         overlay(treescrn6, treescrn8);
466         break;
467     case 4:
468         overlay(treescrn7, treescrn8);
469         break;
470     }
471     touchwin(treescrn8);
472     wrefresh(treescrn8);
473     wrefresh(w_del_msg);
474     look_out(50);
475
476     /*ALL ON************************************************** */
477
478     overlay(treescrn, treescrn8);
479     wrefresh(treescrn8);
480     wrefresh(w_del_msg);
481     look_out(50);
482
483     ++cycle;
484     return (0);
485 }
486
487 static void
488 deer_step(WINDOW *win, int y, int x)
489 {
490     mvwin(win, y, x);
491     wrefresh(win);
492     wrefresh(w_del_msg);
493     look_out(5);
494 }
495
496 static int
497 reindeer(void)
498 {
499     int looper;
500     y_pos = 0;
501
502     for (x_pos = 70; x_pos > 62; x_pos--) {
503         for (looper = 0; looper < 4; looper++) {
504             MvWAddCh(dotdeer0, y_pos, x_pos, (chtype) '.');
505             wrefresh(dotdeer0);
506             wrefresh(w_del_msg);
507             werase(dotdeer0);
508             wrefresh(dotdeer0);
509             wrefresh(w_del_msg);
510             look_out(50);
511         }
512     }
513
514     y_pos = 2;
515
516     for (; x_pos > 50; x_pos--) {
517         for (looper = 0; looper < 4; looper++) {
518
519             if (x_pos < 56) {
520                 y_pos = 3;
521
522                 MvWAddCh(stardeer0, y_pos, x_pos, (chtype) '*');
523                 wrefresh(stardeer0);
524                 wrefresh(w_del_msg);
525                 werase(stardeer0);
526                 wrefresh(stardeer0);
527                 wrefresh(w_del_msg);
528             } else {
529                 MvWAddCh(dotdeer0, y_pos, x_pos, (chtype) '*');
530                 wrefresh(dotdeer0);
531                 wrefresh(w_del_msg);
532                 werase(dotdeer0);
533                 wrefresh(dotdeer0);
534                 wrefresh(w_del_msg);
535             }
536         }
537     }
538
539     x_pos = 58;
540
541     for (y_pos = 2; y_pos < 5; y_pos++) {
542
543         touchwin(lildeer0);
544         wrefresh(lildeer0);
545         wrefresh(w_del_msg);
546
547         for (looper = 0; looper < 4; looper++) {
548             deer_step(lildeer3, y_pos, x_pos);
549             deer_step(lildeer2, y_pos, x_pos);
550             deer_step(lildeer1, y_pos, x_pos);
551             deer_step(lildeer2, y_pos, x_pos);
552             deer_step(lildeer3, y_pos, x_pos);
553
554             touchwin(lildeer0);
555             wrefresh(lildeer0);
556             wrefresh(w_del_msg);
557
558             x_pos -= 2;
559         }
560     }
561
562     x_pos = 35;
563
564     for (y_pos = 5; y_pos < 10; y_pos++) {
565
566         touchwin(middeer0);
567         wrefresh(middeer0);
568         wrefresh(w_del_msg);
569
570         for (looper = 0; looper < 2; looper++) {
571             deer_step(middeer3, y_pos, x_pos);
572             deer_step(middeer2, y_pos, x_pos);
573             deer_step(middeer1, y_pos, x_pos);
574             deer_step(middeer2, y_pos, x_pos);
575             deer_step(middeer3, y_pos, x_pos);
576
577             touchwin(middeer0);
578             wrefresh(middeer0);
579             wrefresh(w_del_msg);
580
581             x_pos -= 3;
582         }
583     }
584
585     look_out(300);
586
587     y_pos = 1;
588
589     for (x_pos = 8; x_pos < 16; x_pos++) {
590         deer_step(bigdeer4, y_pos, x_pos);
591         deer_step(bigdeer3, y_pos, x_pos);
592         deer_step(bigdeer2, y_pos, x_pos);
593         deer_step(bigdeer1, y_pos, x_pos);
594         deer_step(bigdeer2, y_pos, x_pos);
595         deer_step(bigdeer3, y_pos, x_pos);
596         deer_step(bigdeer4, y_pos, x_pos);
597         deer_step(bigdeer0, y_pos, x_pos);
598     }
599
600     --x_pos;
601
602     for (looper = 0; looper < 6; looper++) {
603         deer_step(lookdeer4, y_pos, x_pos);
604         deer_step(lookdeer3, y_pos, x_pos);
605         deer_step(lookdeer2, y_pos, x_pos);
606         deer_step(lookdeer1, y_pos, x_pos);
607         deer_step(lookdeer2, y_pos, x_pos);
608         deer_step(lookdeer3, y_pos, x_pos);
609         deer_step(lookdeer4, y_pos, x_pos);
610     }
611
612     deer_step(lookdeer0, y_pos, x_pos);
613
614     for (; y_pos < 10; y_pos++) {
615         for (looper = 0; looper < 2; looper++) {
616             deer_step(bigdeer4, y_pos, x_pos);
617             deer_step(bigdeer3, y_pos, x_pos);
618             deer_step(bigdeer2, y_pos, x_pos);
619             deer_step(bigdeer1, y_pos, x_pos);
620             deer_step(bigdeer2, y_pos, x_pos);
621             deer_step(bigdeer3, y_pos, x_pos);
622             deer_step(bigdeer4, y_pos, x_pos);
623         }
624         deer_step(bigdeer0, y_pos, x_pos);
625     }
626
627     --y_pos;
628
629     deer_step(lookdeer3, y_pos, x_pos);
630     return (0);
631 }
632
633 static void
634 done(int sig GCC_UNUSED)
635 {
636     move(LINES - 1, 0);
637     refresh();
638     stop_curses();
639
640 #if NO_LEAKS
641     if (my_pairs != 0)
642         free(my_pairs);
643 #endif
644
645     ExitProgram(EXIT_SUCCESS);
646 }
647
648 static void
649 usage(void)
650 {
651     static const char *msg[] =
652     {
653         "Usage: xmas [options]"
654         ,""
655         ,"Options:"
656 #if HAVE_USE_DEFAULT_COLORS
657         ," -d       invoke use_default_colors"
658 #endif
659         ," -q       execute once, then quit"
660     };
661     size_t n;
662
663     for (n = 0; n < SIZEOF(msg); n++)
664         fprintf(stderr, "%s\n", msg[n]);
665
666     ExitProgram(EXIT_FAILURE);
667 }
668
669 int
670 main(int argc, char *argv[])
671 {
672     int ch;
673     int loopy;
674 #if HAVE_USE_DEFAULT_COLORS
675     bool opt_d = FALSE;
676 #endif
677     bool opt_q = FALSE;
678
679     while ((ch = getopt(argc, argv, "dq")) != -1) {
680         switch (ch) {
681 #if HAVE_USE_DEFAULT_COLORS
682         case 'd':
683             opt_d = TRUE;
684             break;
685 #endif
686         case 'q':
687             opt_q = TRUE;
688             break;
689         default:
690             usage();
691             /* NOTREACHED */
692         }
693     }
694
695     setlocale(LC_ALL, "");
696
697     InitAndCatch(initscr(), done);
698     noecho();
699     nonl();
700     refresh();
701
702     if (has_colors()) {
703         start_color();
704 #if HAVE_USE_DEFAULT_COLORS
705         if (opt_d && (use_default_colors() == OK))
706             my_bg = -1;
707 #endif
708     }
709     curs_set(0);
710
711     if ((treescrn = newwin(16, 27, 3, 53)) == 0 ||
712         (treescrn2 = newwin(16, 27, 3, 53)) == 0 ||
713         (treescrn3 = newwin(16, 27, 3, 53)) == 0 ||
714         (treescrn4 = newwin(16, 27, 3, 53)) == 0 ||
715         (treescrn5 = newwin(16, 27, 3, 53)) == 0 ||
716         (treescrn6 = newwin(16, 27, 3, 53)) == 0 ||
717         (treescrn7 = newwin(16, 27, 3, 53)) == 0 ||
718         (treescrn8 = newwin(16, 27, 3, 53)) == 0 ||
719
720         (dotdeer0 = newwin(3, 71, 0, 8)) == 0 ||
721
722         (stardeer0 = newwin(4, 56, 0, 8)) == 0 ||
723
724         (lildeer0 = newwin(7, 53, 0, 8)) == 0 ||
725         (lildeer1 = newwin(2, 4, 0, 0)) == 0 ||
726         (lildeer2 = newwin(2, 4, 0, 0)) == 0 ||
727         (lildeer3 = newwin(2, 4, 0, 0)) == 0 ||
728
729         (middeer0 = newwin(15, 42, 0, 8)) == 0 ||
730         (middeer1 = newwin(3, 7, 0, 0)) == 0 ||
731         (middeer2 = newwin(3, 7, 0, 0)) == 0 ||
732         (middeer3 = newwin(3, 7, 0, 0)) == 0 ||
733
734         (bigdeer0 = newwin(10, 23, 0, 0)) == 0 ||
735         (bigdeer1 = newwin(10, 23, 0, 0)) == 0 ||
736         (bigdeer2 = newwin(10, 23, 0, 0)) == 0 ||
737         (bigdeer3 = newwin(10, 23, 0, 0)) == 0 ||
738         (bigdeer4 = newwin(10, 23, 0, 0)) == 0 ||
739
740         (lookdeer0 = newwin(10, 25, 0, 0)) == 0 ||
741         (lookdeer1 = newwin(10, 25, 0, 0)) == 0 ||
742         (lookdeer2 = newwin(10, 25, 0, 0)) == 0 ||
743         (lookdeer3 = newwin(10, 25, 0, 0)) == 0 ||
744         (lookdeer4 = newwin(10, 25, 0, 0)) == 0 ||
745
746         (w_holiday = newwin(1, 26, 3, 27)) == 0 ||
747
748         (w_del_msg = newwin(1, 19, 23, 60)) == 0) {
749         stop_curses();
750         fprintf(stderr, "Cannot create windows - screen too small\n");
751         ExitProgram(EXIT_FAILURE);
752     }
753
754     MvWAddStr(w_del_msg, 0, 0, "Hit any key to quit");
755
756     MvWAddStr(w_holiday, 0, 0, "H A P P Y  H O L I D A Y S");
757
758     /* set up the windows for our various reindeer */
759
760     /* lildeer1 */
761     MvWAddCh(lildeer1, 0, 0, (chtype) 'V');
762     MvWAddCh(lildeer1, 1, 0, (chtype) '@');
763     MvWAddCh(lildeer1, 1, 1, (chtype) '<');
764     MvWAddCh(lildeer1, 1, 2, (chtype) '>');
765     MvWAddCh(lildeer1, 1, 3, (chtype) '~');
766
767     /* lildeer2 */
768     MvWAddCh(lildeer2, 0, 0, (chtype) 'V');
769     MvWAddCh(lildeer2, 1, 0, (chtype) '@');
770     MvWAddCh(lildeer2, 1, 1, (chtype) '|');
771     MvWAddCh(lildeer2, 1, 2, (chtype) '|');
772     MvWAddCh(lildeer2, 1, 3, (chtype) '~');
773
774     /* lildeer3 */
775     MvWAddCh(lildeer3, 0, 0, (chtype) 'V');
776     MvWAddCh(lildeer3, 1, 0, (chtype) '@');
777     MvWAddCh(lildeer3, 1, 1, (chtype) '>');
778     MvWAddCh(lildeer3, 1, 2, (chtype) '<');
779     MvWAddCh(lildeer2, 1, 3, (chtype) '~');
780
781     /* middeer1 */
782     MvWAddCh(middeer1, 0, 2, (chtype) 'y');
783     MvWAddCh(middeer1, 0, 3, (chtype) 'y');
784     MvWAddCh(middeer1, 1, 2, (chtype) '0');
785     MvWAddCh(middeer1, 1, 3, (chtype) '(');
786     MvWAddCh(middeer1, 1, 4, (chtype) '=');
787     MvWAddCh(middeer1, 1, 5, (chtype) ')');
788     MvWAddCh(middeer1, 1, 6, (chtype) '~');
789     MvWAddCh(middeer1, 2, 3, (chtype) '\\');
790     MvWAddCh(middeer1, 2, 4, (chtype) '/');
791
792     /* middeer2 */
793     MvWAddCh(middeer2, 0, 2, (chtype) 'y');
794     MvWAddCh(middeer2, 0, 3, (chtype) 'y');
795     MvWAddCh(middeer2, 1, 2, (chtype) '0');
796     MvWAddCh(middeer2, 1, 3, (chtype) '(');
797     MvWAddCh(middeer2, 1, 4, (chtype) '=');
798     MvWAddCh(middeer2, 1, 5, (chtype) ')');
799     MvWAddCh(middeer2, 1, 6, (chtype) '~');
800     MvWAddCh(middeer2, 2, 3, (chtype) '|');
801     MvWAddCh(middeer2, 2, 5, (chtype) '|');
802
803     /* middeer3 */
804     MvWAddCh(middeer3, 0, 2, (chtype) 'y');
805     MvWAddCh(middeer3, 0, 3, (chtype) 'y');
806     MvWAddCh(middeer3, 1, 2, (chtype) '0');
807     MvWAddCh(middeer3, 1, 3, (chtype) '(');
808     MvWAddCh(middeer3, 1, 4, (chtype) '=');
809     MvWAddCh(middeer3, 1, 5, (chtype) ')');
810     MvWAddCh(middeer3, 1, 6, (chtype) '~');
811     MvWAddCh(middeer3, 2, 2, (chtype) '/');
812     MvWAddCh(middeer3, 2, 6, (chtype) '\\');
813
814     /* bigdeer1 */
815     MvWAddCh(bigdeer1, 0, 17, (chtype) '\\');
816     MvWAddCh(bigdeer1, 0, 18, (chtype) '/');
817     MvWAddCh(bigdeer1, 0, 20, (chtype) '\\');
818     MvWAddCh(bigdeer1, 0, 21, (chtype) '/');
819     MvWAddCh(bigdeer1, 1, 18, (chtype) '\\');
820     MvWAddCh(bigdeer1, 1, 20, (chtype) '/');
821     MvWAddCh(bigdeer1, 2, 19, (chtype) '|');
822     MvWAddCh(bigdeer1, 2, 20, (chtype) '_');
823     MvWAddCh(bigdeer1, 3, 18, (chtype) '/');
824     MvWAddCh(bigdeer1, 3, 19, (chtype) '^');
825     MvWAddCh(bigdeer1, 3, 20, (chtype) '0');
826     MvWAddCh(bigdeer1, 3, 21, (chtype) '\\');
827     MvWAddCh(bigdeer1, 4, 17, (chtype) '/');
828     MvWAddCh(bigdeer1, 4, 18, (chtype) '/');
829     MvWAddCh(bigdeer1, 4, 19, (chtype) '\\');
830     MvWAddCh(bigdeer1, 4, 22, (chtype) '\\');
831     MvWAddStr(bigdeer1, 5, 7, "^~~~~~~~~//  ~~U");
832     MvWAddStr(bigdeer1, 6, 7, "( \\_____( /");
833     MvWAddStr(bigdeer1, 7, 8, "( )    /");
834     MvWAddStr(bigdeer1, 8, 9, "\\\\   /");
835     MvWAddStr(bigdeer1, 9, 11, "\\>/>");
836
837     /* bigdeer2 */
838     MvWAddCh(bigdeer2, 0, 17, (chtype) '\\');
839     MvWAddCh(bigdeer2, 0, 18, (chtype) '/');
840     MvWAddCh(bigdeer2, 0, 20, (chtype) '\\');
841     MvWAddCh(bigdeer2, 0, 21, (chtype) '/');
842     MvWAddCh(bigdeer2, 1, 18, (chtype) '\\');
843     MvWAddCh(bigdeer2, 1, 20, (chtype) '/');
844     MvWAddCh(bigdeer2, 2, 19, (chtype) '|');
845     MvWAddCh(bigdeer2, 2, 20, (chtype) '_');
846     MvWAddCh(bigdeer2, 3, 18, (chtype) '/');
847     MvWAddCh(bigdeer2, 3, 19, (chtype) '^');
848     MvWAddCh(bigdeer2, 3, 20, (chtype) '0');
849     MvWAddCh(bigdeer2, 3, 21, (chtype) '\\');
850     MvWAddCh(bigdeer2, 4, 17, (chtype) '/');
851     MvWAddCh(bigdeer2, 4, 18, (chtype) '/');
852     MvWAddCh(bigdeer2, 4, 19, (chtype) '\\');
853     MvWAddCh(bigdeer2, 4, 22, (chtype) '\\');
854     MvWAddStr(bigdeer2, 5, 7, "^~~~~~~~~//  ~~U");
855     MvWAddStr(bigdeer2, 6, 7, "(( )____( /");
856     MvWAddStr(bigdeer2, 7, 7, "( /      |");
857     MvWAddStr(bigdeer2, 8, 8, "\\/      |");
858     MvWAddStr(bigdeer2, 9, 9, "|>     |>");
859
860     /* bigdeer3 */
861     MvWAddCh(bigdeer3, 0, 17, (chtype) '\\');
862     MvWAddCh(bigdeer3, 0, 18, (chtype) '/');
863     MvWAddCh(bigdeer3, 0, 20, (chtype) '\\');
864     MvWAddCh(bigdeer3, 0, 21, (chtype) '/');
865     MvWAddCh(bigdeer3, 1, 18, (chtype) '\\');
866     MvWAddCh(bigdeer3, 1, 20, (chtype) '/');
867     MvWAddCh(bigdeer3, 2, 19, (chtype) '|');
868     MvWAddCh(bigdeer3, 2, 20, (chtype) '_');
869     MvWAddCh(bigdeer3, 3, 18, (chtype) '/');
870     MvWAddCh(bigdeer3, 3, 19, (chtype) '^');
871     MvWAddCh(bigdeer3, 3, 20, (chtype) '0');
872     MvWAddCh(bigdeer3, 3, 21, (chtype) '\\');
873     MvWAddCh(bigdeer3, 4, 17, (chtype) '/');
874     MvWAddCh(bigdeer3, 4, 18, (chtype) '/');
875     MvWAddCh(bigdeer3, 4, 19, (chtype) '\\');
876     MvWAddCh(bigdeer3, 4, 22, (chtype) '\\');
877     MvWAddStr(bigdeer3, 5, 7, "^~~~~~~~~//  ~~U");
878     MvWAddStr(bigdeer3, 6, 6, "( ()_____( /");
879     MvWAddStr(bigdeer3, 7, 6, "/ /       /");
880     MvWAddStr(bigdeer3, 8, 5, "|/          \\");
881     MvWAddStr(bigdeer3, 9, 5, "/>           \\>");
882
883     /* bigdeer4 */
884     MvWAddCh(bigdeer4, 0, 17, (chtype) '\\');
885     MvWAddCh(bigdeer4, 0, 18, (chtype) '/');
886     MvWAddCh(bigdeer4, 0, 20, (chtype) '\\');
887     MvWAddCh(bigdeer4, 0, 21, (chtype) '/');
888     MvWAddCh(bigdeer4, 1, 18, (chtype) '\\');
889     MvWAddCh(bigdeer4, 1, 20, (chtype) '/');
890     MvWAddCh(bigdeer4, 2, 19, (chtype) '|');
891     MvWAddCh(bigdeer4, 2, 20, (chtype) '_');
892     MvWAddCh(bigdeer4, 3, 18, (chtype) '/');
893     MvWAddCh(bigdeer4, 3, 19, (chtype) '^');
894     MvWAddCh(bigdeer4, 3, 20, (chtype) '0');
895     MvWAddCh(bigdeer4, 3, 21, (chtype) '\\');
896     MvWAddCh(bigdeer4, 4, 17, (chtype) '/');
897     MvWAddCh(bigdeer4, 4, 18, (chtype) '/');
898     MvWAddCh(bigdeer4, 4, 19, (chtype) '\\');
899     MvWAddCh(bigdeer4, 4, 22, (chtype) '\\');
900     MvWAddStr(bigdeer4, 5, 7, "^~~~~~~~~//  ~~U");
901     MvWAddStr(bigdeer4, 6, 6, "( )______( /");
902     MvWAddStr(bigdeer4, 7, 5, "(/          \\");
903     MvWAddStr(bigdeer4, 8, 0, "v___=             ----^");
904
905     /* lookdeer1 */
906     MvWAddStr(lookdeer1, 0, 16, "\\/     \\/");
907     MvWAddStr(lookdeer1, 1, 17, "\\Y/ \\Y/");
908     MvWAddStr(lookdeer1, 2, 19, "\\=/");
909     MvWAddStr(lookdeer1, 3, 17, "^\\o o/^");
910     MvWAddStr(lookdeer1, 4, 17, "//( )");
911     MvWAddStr(lookdeer1, 5, 7, "^~~~~~~~~// \\O/");
912     MvWAddStr(lookdeer1, 6, 7, "( \\_____( /");
913     MvWAddStr(lookdeer1, 7, 8, "( )    /");
914     MvWAddStr(lookdeer1, 8, 9, "\\\\   /");
915     MvWAddStr(lookdeer1, 9, 11, "\\>/>");
916
917     /* lookdeer2 */
918     MvWAddStr(lookdeer2, 0, 16, "\\/     \\/");
919     MvWAddStr(lookdeer2, 1, 17, "\\Y/ \\Y/");
920     MvWAddStr(lookdeer2, 2, 19, "\\=/");
921     MvWAddStr(lookdeer2, 3, 17, "^\\o o/^");
922     MvWAddStr(lookdeer2, 4, 17, "//( )");
923     MvWAddStr(lookdeer2, 5, 7, "^~~~~~~~~// \\O/");
924     MvWAddStr(lookdeer2, 6, 7, "(( )____( /");
925     MvWAddStr(lookdeer2, 7, 7, "( /      |");
926     MvWAddStr(lookdeer2, 8, 8, "\\/      |");
927     MvWAddStr(lookdeer2, 9, 9, "|>     |>");
928
929     /* lookdeer3 */
930     MvWAddStr(lookdeer3, 0, 16, "\\/     \\/");
931     MvWAddStr(lookdeer3, 1, 17, "\\Y/ \\Y/");
932     MvWAddStr(lookdeer3, 2, 19, "\\=/");
933     MvWAddStr(lookdeer3, 3, 17, "^\\o o/^");
934     MvWAddStr(lookdeer3, 4, 17, "//( )");
935     MvWAddStr(lookdeer3, 5, 7, "^~~~~~~~~// \\O/");
936     MvWAddStr(lookdeer3, 6, 6, "( ()_____( /");
937     MvWAddStr(lookdeer3, 7, 6, "/ /       /");
938     MvWAddStr(lookdeer3, 8, 5, "|/          \\");
939     MvWAddStr(lookdeer3, 9, 5, "/>           \\>");
940
941     /* lookdeer4 */
942     MvWAddStr(lookdeer4, 0, 16, "\\/     \\/");
943     MvWAddStr(lookdeer4, 1, 17, "\\Y/ \\Y/");
944     MvWAddStr(lookdeer4, 2, 19, "\\=/");
945     MvWAddStr(lookdeer4, 3, 17, "^\\o o/^");
946     MvWAddStr(lookdeer4, 4, 17, "//( )");
947     MvWAddStr(lookdeer4, 5, 7, "^~~~~~~~~// \\O/");
948     MvWAddStr(lookdeer4, 6, 6, "( )______( /");
949     MvWAddStr(lookdeer4, 7, 5, "(/          \\");
950     MvWAddStr(lookdeer4, 8, 0, "v___=             ----^");
951
952         /***********************************************/
953     cbreak();
954     nodelay(stdscr, TRUE);
955     do {
956         clear();
957         werase(treescrn);
958         touchwin(w_del_msg);
959         touchwin(treescrn);
960         werase(treescrn2);
961         touchwin(treescrn2);
962         werase(treescrn8);
963         touchwin(treescrn8);
964         refresh();
965         look_out(150);
966         boxit();
967         refresh();
968         look_out(150);
969         seas();
970         refresh();
971         look_out(150);
972         greet();
973         refresh();
974         look_out(150);
975         fromwho();
976         refresh();
977         look_out(150);
978         tree();
979         look_out(150);
980         balls();
981         look_out(150);
982         star();
983         look_out(150);
984         strng1();
985         strng2();
986         strng3();
987         strng4();
988         strng5();
989
990         /* set up the windows for our blinking trees */
991         /* **************************************** */
992         /* treescrn3 */
993
994         overlay(treescrn, treescrn3);
995
996         /*balls */
997         MvWAddCh(treescrn3, 4, 18, ' ');
998         MvWAddCh(treescrn3, 7, 6, ' ');
999         MvWAddCh(treescrn3, 8, 19, ' ');
1000         MvWAddCh(treescrn3, 11, 22, ' ');
1001
1002         /*star */
1003         MvWAddCh(treescrn3, 0, 12, '*');
1004
1005         /*strng1 */
1006         MvWAddCh(treescrn3, 3, 11, ' ');
1007
1008         /*strng2 */
1009         MvWAddCh(treescrn3, 5, 13, ' ');
1010         MvWAddCh(treescrn3, 6, 10, ' ');
1011
1012         /*strng3 */
1013         MvWAddCh(treescrn3, 7, 16, ' ');
1014         MvWAddCh(treescrn3, 7, 14, ' ');
1015
1016         /*strng4 */
1017         MvWAddCh(treescrn3, 10, 13, ' ');
1018         MvWAddCh(treescrn3, 10, 10, ' ');
1019         MvWAddCh(treescrn3, 11, 8, ' ');
1020
1021         /*strng5 */
1022         MvWAddCh(treescrn3, 11, 18, ' ');
1023         MvWAddCh(treescrn3, 12, 13, ' ');
1024
1025         /* treescrn4 */
1026
1027         overlay(treescrn, treescrn4);
1028
1029         /*balls */
1030         MvWAddCh(treescrn4, 3, 9, ' ');
1031         MvWAddCh(treescrn4, 4, 16, ' ');
1032         MvWAddCh(treescrn4, 7, 6, ' ');
1033         MvWAddCh(treescrn4, 8, 19, ' ');
1034         MvWAddCh(treescrn4, 11, 2, ' ');
1035         MvWAddCh(treescrn4, 12, 23, ' ');
1036
1037         /*star */
1038         (void) wstandout(treescrn4);
1039         MvWAddCh(treescrn4, 0, 12, '*');
1040         (void) wstandend(treescrn4);
1041
1042         /*strng1 */
1043         MvWAddCh(treescrn4, 3, 13, ' ');
1044
1045         /*strng2 */
1046
1047         /*strng3 */
1048         MvWAddCh(treescrn4, 7, 15, ' ');
1049         MvWAddCh(treescrn4, 8, 11, ' ');
1050
1051         /*strng4 */
1052         MvWAddCh(treescrn4, 9, 16, ' ');
1053         MvWAddCh(treescrn4, 10, 12, ' ');
1054         MvWAddCh(treescrn4, 11, 8, ' ');
1055
1056         /*strng5 */
1057         MvWAddCh(treescrn4, 11, 18, ' ');
1058         MvWAddCh(treescrn4, 12, 14, ' ');
1059
1060         /* treescrn5 */
1061
1062         overlay(treescrn, treescrn5);
1063
1064         /*balls */
1065         MvWAddCh(treescrn5, 3, 15, ' ');
1066         MvWAddCh(treescrn5, 10, 20, ' ');
1067         MvWAddCh(treescrn5, 12, 1, ' ');
1068
1069         /*star */
1070         MvWAddCh(treescrn5, 0, 12, '*');
1071
1072         /*strng1 */
1073         MvWAddCh(treescrn5, 3, 11, ' ');
1074
1075         /*strng2 */
1076         MvWAddCh(treescrn5, 5, 12, ' ');
1077
1078         /*strng3 */
1079         MvWAddCh(treescrn5, 7, 14, ' ');
1080         MvWAddCh(treescrn5, 8, 10, ' ');
1081
1082         /*strng4 */
1083         MvWAddCh(treescrn5, 9, 15, ' ');
1084         MvWAddCh(treescrn5, 10, 11, ' ');
1085         MvWAddCh(treescrn5, 11, 7, ' ');
1086
1087         /*strng5 */
1088         MvWAddCh(treescrn5, 11, 17, ' ');
1089         MvWAddCh(treescrn5, 12, 13, ' ');
1090
1091         /* treescrn6 */
1092
1093         overlay(treescrn, treescrn6);
1094
1095         /*balls */
1096         MvWAddCh(treescrn6, 6, 7, ' ');
1097         MvWAddCh(treescrn6, 7, 18, ' ');
1098         MvWAddCh(treescrn6, 10, 4, ' ');
1099         MvWAddCh(treescrn6, 11, 23, ' ');
1100
1101         /*star */
1102         (void) wstandout(treescrn6);
1103         MvWAddCh(treescrn6, 0, 12, '*');
1104         (void) wstandend(treescrn6);
1105
1106         /*strng1 */
1107
1108         /*strng2 */
1109         MvWAddCh(treescrn6, 5, 11, ' ');
1110
1111         /*strng3 */
1112         MvWAddCh(treescrn6, 7, 13, ' ');
1113         MvWAddCh(treescrn6, 8, 9, ' ');
1114
1115         /*strng4 */
1116         MvWAddCh(treescrn6, 9, 14, ' ');
1117         MvWAddCh(treescrn6, 10, 10, ' ');
1118         MvWAddCh(treescrn6, 11, 6, ' ');
1119
1120         /*strng5 */
1121         MvWAddCh(treescrn6, 11, 16, ' ');
1122         MvWAddCh(treescrn6, 12, 12, ' ');
1123
1124         /* treescrn7 */
1125
1126         overlay(treescrn, treescrn7);
1127
1128         /*balls */
1129         MvWAddCh(treescrn7, 3, 15, ' ');
1130         MvWAddCh(treescrn7, 6, 7, ' ');
1131         MvWAddCh(treescrn7, 7, 18, ' ');
1132         MvWAddCh(treescrn7, 10, 4, ' ');
1133         MvWAddCh(treescrn7, 11, 22, ' ');
1134
1135         /*star */
1136         MvWAddCh(treescrn7, 0, 12, '*');
1137
1138         /*strng1 */
1139         MvWAddCh(treescrn7, 3, 12, ' ');
1140
1141         /*strng2 */
1142         MvWAddCh(treescrn7, 5, 13, ' ');
1143         MvWAddCh(treescrn7, 6, 9, ' ');
1144
1145         /*strng3 */
1146         MvWAddCh(treescrn7, 7, 15, ' ');
1147         MvWAddCh(treescrn7, 8, 11, ' ');
1148
1149         /*strng4 */
1150         MvWAddCh(treescrn7, 9, 16, ' ');
1151         MvWAddCh(treescrn7, 10, 12, ' ');
1152         MvWAddCh(treescrn7, 11, 8, ' ');
1153
1154         /*strng5 */
1155         MvWAddCh(treescrn7, 11, 18, ' ');
1156         MvWAddCh(treescrn7, 12, 14, ' ');
1157
1158         look_out(150);
1159         reindeer();
1160
1161         touchwin(w_holiday);
1162         wrefresh(w_holiday);
1163         wrefresh(w_del_msg);
1164
1165         look_out(500);
1166         for (loopy = 0; loopy < 100; loopy++) {
1167             blinkit();
1168         }
1169     } while (!opt_q);
1170     done(0);
1171 }