1 /* phoon - show the phase of the moon
4 --- ------- --- -------------------------------------------------------------
5 01A 08nov86 JP Translated from the ratfor version of 12nov85, which itself
6 was translated from the Pascal version of 05apr79.
8 Copyright (C) 1986 by Jeffrey A. Poskanzer. Permission to use, copy,
9 modify, and distribute this software and its documentation for any
10 purpose and without fee is hereby granted, provided that this copyright
11 notice appear in all copies and in all supporting documentation. No
12 representation is made about the suitability of this software for any
13 purpose. It is provided "as is" without express or implied warranty.
17 static char copyright[] = "\nCopyright (C) 1986 by Jeffrey A. Poskanzer.\n";
25 /* Global defines and declarations. */
27 #define SECSPERMINUTE 60
28 #define SECSPERHOUR (60 * SECSPERMINUTE)
29 #define SECSPERDAY (24 * SECSPERHOUR)
34 #define ASPECTRATIO 0.5
35 #define MOONSTARTCOL 18
36 #define QUARTERLITLEN 16
37 #define QUARTERLITLENPLUSONE 17
42 main( argc, argv, envp )
44 char *argv[], *envp[];
49 /* Figure out what date and time to use. */
52 /* No arguments present - use the current date and time. */
53 twscopy( &t, dtwstime( ) );
55 else if ( argc == 2 || argc == 3 || argc == 4 )
57 /* One, two, or three args - use them. */
58 strcpy( buf, argv[1] );
62 strcat( buf, argv[2] );
66 strcat( buf, argv[3] );
69 twp = dparsetime( buf );
70 if ( twp == NULL || twp -> tw_flags & TW_JUNK )
72 fprintf( stderr, "illegal date/time: %s\n", buf );
80 fprintf( stderr, "usage: %s [ <date/time> ]\n", argv[0] );
84 /* Pseudo-randomly decide what the moon is made of, and print it. */
85 if ( twclock( dtwstime( ) ) % 17 == 3 )
86 putmoon( &t, "GREENCHEESE" );
95 putmoon( t, atfiller )
99 struct tws twsanewmoon;
100 long secsynodic = 29*SECSPERDAY + 12*SECSPERHOUR + 44*SECSPERMINUTE + 3;
101 long secdiff, secphase;
102 int atflrlen, atflridx, lin, col, midlin, qlitidx;
103 float angphase, mcap, yrad, xrad, y, xright, xleft;
104 int colright, colleft, i;
107 static char background[NUMLINES][47] = {
111 " .-'@ @@@@@@@ . @@@@@ `-. ",
112 " /@@@ @@@@@@@@@@@ @@@@@@@ . \\ ",
113 " ./ o @@@@@@@@@@@ @@@@@@@ . \\. ",
114 " /@@ o @@@@@@@@@@@. @@@@@@@ O \\ ",
115 " /@@@@ . @@@@@@@o @@@@@@@@@@ @@@ \\ ",
116 " |@@@@@ . @@@@@@@@@@@@@ o @@@@| ",
117 " /@@@@@ O `.-./ . @@@@@@@@@@@@ @@ \\",
118 " | @@@@ --`-' o @@@@@@@@ @@@@ |",
119 " |@ @@@ ` o . @@ . @@@@@@@ |",
120 " | @@ .-. @@@ @@@@@@@ |",
121 " \\ . o @@@ `-' . @@@@ @@@@ o /",
122 " | @@ @@@@@ . @@ . | ",
123 " \\ @@@@ @\\@@ / . O . o . / ",
124 " \\ o @@ \\ \\ / . . / ",
125 " `\\ . .\\.-.___ . . .-. /' ",
127 " `-. o / | o O . .-' ",
130 " `------------' " };
132 static char qlits[8][16] = {
143 /* Find the length of the atfiller string. */
144 atflrlen = strlen( atfiller );
146 /* Convert a new moon date from a string to a tws. */
147 twscopy( &twsanewmoon, dparsetime( "05jan81 23:24:00 PST" ) );
149 /* Subtract the new moon date from the desired date to get the interval
150 since the new moon. */
151 secdiff = twsubtract( t, &twsanewmoon );
153 /* Figure out the phase - the interval since the last new moon. */
154 secphase = secdiff % secsynodic;
156 secphase += secsynodic; /* fucking mathematician language designers */
157 angphase = (float) secphase / (float) secsynodic * 2.0 * PI;
158 mcap = -cos( angphase );
160 /* Figure out how big the moon is. */
161 yrad = NUMLINES / 2.0;
162 xrad = yrad / ASPECTRATIO;
164 /* Figure out some other random stuff. */
165 midlin = NUMLINES / 2;
166 qlitidx = angphase / PI * 2.0;
168 /* Now output the moon, a slice at a time. */
170 for ( lin = 0; lin < NUMLINES; lin = lin + 1 )
172 /* Compute the edges of this slice. */
173 y = lin + 0.5 - yrad;
174 xright = xrad * sqrt( 1.0 - ( y * y ) / ( yrad * yrad ) );
176 if ( angphase >= 0.0 && angphase < PI )
177 xleft = mcap * xleft;
179 xright = mcap * xright;
180 colleft = (int) (xrad + 0.5) + (int) (xleft + 0.5);
181 colright = (int) (xrad + 0.5) + (int) (xright + 0.5);
183 /* Now output the slice. */
184 for ( i = 0; i < colleft; i++ )
186 for ( col = colleft; col <= colright; col = col + 1 )
187 if ( ( c = background[lin][col] ) != '@' )
191 putchar( atfiller[atflridx] );
192 atflridx = (atflridx + 1) % atflrlen;
195 /* Output the end-of-line information, if any. */
196 if ( lin == midlin - 2 )
200 fputs( qlits[qlitidx], stdout );
202 else if ( lin == midlin - 1)
206 putseconds( secphase % (secsynodic / 4) );
208 else if ( lin == midlin )
212 fputs( qlits[qlitidx + 4], stdout );
214 else if ( lin == midlin + 1 )
218 putseconds( (secsynodic - secphase) % (secsynodic / 4) );
230 long days, hours, minutes;
232 days = secs / SECSPERDAY;
233 secs = secs - days * SECSPERDAY;
234 hours = secs / SECSPERHOUR;
235 secs = secs - hours * SECSPERHOUR;
236 minutes = secs / SECSPERMINUTE;
237 secs = secs - minutes * SECSPERMINUTE;
239 printf( "%ld %2ld:%02ld:%02ld", days, hours, minutes, secs );