]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/zotnet/tws/phoon/phoon.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / zotnet / tws / phoon / phoon.c
1 /* phoon - show the phase of the moon
2
3 ver date who remarks
4 --- ------- --- -------------------------------------------------------------
5 01A 08nov86 JP Translated from the ratfor version of 12nov85, which itself
6 was translated from the Pascal version of 05apr79.
7
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.
14
15 */
16
17 static char copyright[] = "\nCopyright (C) 1986 by Jeffrey A. Poskanzer.\n";
18
19
20 #include <stdio.h>
21 #include <math.h>
22 #include "tws.h"
23
24
25 /* Global defines and declarations. */
26
27 #define SECSPERMINUTE 60
28 #define SECSPERHOUR (60 * SECSPERMINUTE)
29 #define SECSPERDAY (24 * SECSPERHOUR)
30
31 #define PI 3.14159
32
33 #define NUMLINES 23
34 #define ASPECTRATIO 0.5
35 #define MOONSTARTCOL 18
36 #define QUARTERLITLEN 16
37 #define QUARTERLITLENPLUSONE 17
38
39
40 /* Main program. */
41
42 main( argc, argv, envp )
43 int argc;
44 char *argv[], *envp[];
45 {
46 struct tws t, *twp;
47 char buf[100];
48
49 /* Figure out what date and time to use. */
50 if ( argc == 1 )
51 {
52 /* No arguments present - use the current date and time. */
53 twscopy( &t, dtwstime( ) );
54 }
55 else if ( argc == 2 || argc == 3 || argc == 4 )
56 {
57 /* One, two, or three args - use them. */
58 strcpy( buf, argv[1] );
59 if ( argc > 2 )
60 {
61 strcat( buf, " " );
62 strcat( buf, argv[2] );
63 if ( argc > 3 )
64 {
65 strcat( buf, " " );
66 strcat( buf, argv[3] );
67 }
68 }
69 twp = dparsetime( buf );
70 if ( twp == NULL || twp -> tw_flags & TW_JUNK )
71 {
72 fprintf( stderr, "illegal date/time: %s\n", buf );
73 exit( 1 );
74 }
75 twscopy( &t, twp );
76 }
77 else
78 {
79 /* Too many args! */
80 fprintf( stderr, "usage: %s [ <date/time> ]\n", argv[0] );
81 exit( 1 );
82 }
83
84 /* Pseudo-randomly decide what the moon is made of, and print it. */
85 if ( twclock( dtwstime( ) ) % 17 == 3 )
86 putmoon( &t, "GREENCHEESE" );
87 else
88 putmoon( &t, "@" );
89
90 /* All done. */
91 exit( 0 );
92 }
93
94
95 putmoon( t, atfiller )
96 struct tws *t;
97 char *atfiller;
98 {
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;
105 char c;
106
107 static char background[NUMLINES][47] = {
108 " .------------. ",
109 " .--' o . . `--. ",
110 " .-' . O . . `-. ",
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 " `\\ . .\\.-.___ . . .-. /' ",
126 " \\ `-' `-' / ",
127 " `-. o / | o O . .-' ",
128 " `-. / . . .-' ",
129 " `--. . .--' ",
130 " `------------' " };
131
132 static char qlits[8][16] = {
133 "New Moon + ",
134 "First Quarter +",
135 "Full Moon + ",
136 "Last Quarter + ",
137 "First Quarter -",
138 "Full Moon - ",
139 "Last Quarter - ",
140 "New Moon - " };
141
142
143 /* Find the length of the atfiller string. */
144 atflrlen = strlen( atfiller );
145
146 /* Convert a new moon date from a string to a tws. */
147 twscopy( &twsanewmoon, dparsetime( "05jan81 23:24:00 PST" ) );
148
149 /* Subtract the new moon date from the desired date to get the interval
150 since the new moon. */
151 secdiff = twsubtract( t, &twsanewmoon );
152
153 /* Figure out the phase - the interval since the last new moon. */
154 secphase = secdiff % secsynodic;
155 if ( secphase < 0L )
156 secphase += secsynodic; /* fucking mathematician language designers */
157 angphase = (float) secphase / (float) secsynodic * 2.0 * PI;
158 mcap = -cos( angphase );
159
160 /* Figure out how big the moon is. */
161 yrad = NUMLINES / 2.0;
162 xrad = yrad / ASPECTRATIO;
163
164 /* Figure out some other random stuff. */
165 midlin = NUMLINES / 2;
166 qlitidx = angphase / PI * 2.0;
167
168 /* Now output the moon, a slice at a time. */
169 atflridx = 0;
170 for ( lin = 0; lin < NUMLINES; lin = lin + 1 )
171 {
172 /* Compute the edges of this slice. */
173 y = lin + 0.5 - yrad;
174 xright = xrad * sqrt( 1.0 - ( y * y ) / ( yrad * yrad ) );
175 xleft = -xright;
176 if ( angphase >= 0.0 && angphase < PI )
177 xleft = mcap * xleft;
178 else
179 xright = mcap * xright;
180 colleft = (int) (xrad + 0.5) + (int) (xleft + 0.5);
181 colright = (int) (xrad + 0.5) + (int) (xright + 0.5);
182
183 /* Now output the slice. */
184 for ( i = 0; i < colleft; i++ )
185 putchar( ' ' );
186 for ( col = colleft; col <= colright; col = col + 1 )
187 if ( ( c = background[lin][col] ) != '@' )
188 putchar( c );
189 else
190 {
191 putchar( atfiller[atflridx] );
192 atflridx = (atflridx + 1) % atflrlen;
193 }
194
195 /* Output the end-of-line information, if any. */
196 if ( lin == midlin - 2 )
197 {
198 putchar( '\t' );
199 putchar( '\t' );
200 fputs( qlits[qlitidx], stdout );
201 }
202 else if ( lin == midlin - 1)
203 {
204 putchar( '\t' );
205 putchar( '\t' );
206 putseconds( secphase % (secsynodic / 4) );
207 }
208 else if ( lin == midlin )
209 {
210 putchar( '\t' );
211 putchar( '\t' );
212 fputs( qlits[qlitidx + 4], stdout );
213 }
214 else if ( lin == midlin + 1 )
215 {
216 putchar( '\t' );
217 putchar( '\t' );
218 putseconds( (secsynodic - secphase) % (secsynodic / 4) );
219 }
220
221 putchar( '\n' );
222 }
223
224 }
225
226
227 putseconds( secs )
228 long secs;
229 {
230 long days, hours, minutes;
231
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;
238
239 printf( "%ld %2ld:%02ld:%02ld", days, hours, minutes, secs );
240 }