xref: /original-bsd/games/rain/rain.c (revision 83e03edb)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)rain.c	5.4 (Berkeley) 06/27/88";
26 #endif /* not lint */
27 
28 /*
29  * rain 11/3/1980 EPS/CITHEP
30  * cc rain.c -o rain -O -ltermlib
31  */
32 
33 #include <sys/types.h>
34 #include <stdio.h>
35 #ifdef USG
36 #include <termio.h>
37 #else
38 #include <sgtty.h>
39 #endif
40 #include <signal.h>
41 
42 #define	cursor(c, r)	tputs(tgoto(CM, c, r), 1, fputchar)
43 
44 #ifdef USG
45 static struct termio sg, old_tty;
46 #else
47 static struct sgttyb sg, old_tty;
48 #endif
49 
50 int	fputchar();
51 char	*LL, *TE, *tgoto();
52 
53 main(argc, argv)
54 	int argc;
55 	char **argv;
56 {
57 	extern short ospeed;
58 	extern char *UP;
59 	register int x, y, j;
60 	register char *CM, *BC, *DN, *ND, *term;
61 	char *TI, *tcp, *mp, tcb[100],
62 		*malloc(), *getenv(), *strcpy(), *tgetstr();
63 	long cols, lines, random();
64 	int xpos[5], ypos[5], onsig();
65 
66 	if (!(term = getenv("TERM"))) {
67 		fprintf(stderr, "%s: TERM: parameter not set\n", *argv);
68 		exit(1);
69 	}
70 	if (!(mp = malloc((u_int)1024))) {
71 		fprintf(stderr, "%s: out of space.\n", *argv);
72 		exit(1);
73 	}
74 	if (tgetent(mp, term) <= 0) {
75 		fprintf(stderr, "%s: %s: unknown terminal type\n", *argv, term);
76 		exit(1);
77 	}
78 	tcp = tcb;
79 	if (!(CM = tgetstr("cm", &tcp))) {
80 		fprintf(stderr, "%s: terminal not capable of cursor motion\n", *argv);
81 		exit(1);
82 	}
83 	if (!(BC = tgetstr("bc", &tcp)))
84 		BC = "\b";
85 	if (!(DN = tgetstr("dn", &tcp)))
86 		DN = "\n";
87 	if (!(ND = tgetstr("nd", &tcp)))
88 		ND = " ";
89 	if ((cols = tgetnum("co")) == -1)
90 		cols = 80;
91 	if ((lines = tgetnum("li")) == -1)
92 		lines = 24;
93 	cols -= 4;
94 	lines -= 4;
95 	TE = tgetstr("te", &tcp);
96 	TI = tgetstr("ti", &tcp);
97 	UP = tgetstr("up", &tcp);
98 	if (!(LL = tgetstr("ll", &tcp))) {
99 		if (!(LL = malloc((u_int)10))) {
100 			fprintf(stderr, "%s: out of space.\n", *argv);
101 			exit(1);
102 		}
103 		(void)strcpy(LL, tgoto(CM, 0, 23));
104 	}
105 #ifdef USG
106 	ioctl(1, TCGETA, &sg);
107 	ospeed = sg.c_cflag&CBAUD;
108 #else
109 	gtty(1, &sg);
110 	ospeed = sg.sg_ospeed;
111 #endif
112 	(void)signal(SIGHUP, onsig);
113 	(void)signal(SIGINT, onsig);
114 	(void)signal(SIGQUIT, onsig);
115 	(void)signal(SIGSTOP, onsig);
116 	(void)signal(SIGTSTP, onsig);
117 	(void)signal(SIGTERM, onsig);
118 #ifdef USG
119 	ioctl(1, TCGETA, &old_tty);	/* save tty bits for exit */
120 	ioctl(1, TCGETA, &sg);
121 	sg.c_iflag &= ~ICRNL;
122 	sg.c_oflag &= ~ONLCR;
123 	sg.c_lflag &= ~ECHO;
124 	ioctl(1, TCSETAW, &sg);
125 #else
126 	gtty(1, &old_tty);		/* save tty bits for exit */
127 	gtty(1, &sg);
128 	sg.sg_flags &= ~(CRMOD|ECHO);
129 	stty(1, &sg);
130 #endif
131 	if (TI)
132 		tputs(TI, 1, fputchar);
133 	tputs(tgetstr("cl", &tcp), 1, fputchar);
134 	(void)fflush(stdout);
135 	for (j = 4; j >= 0; --j) {
136 		xpos[j] = random() % cols + 2;
137 		ypos[j] = random() % lines + 2;
138 	}
139 	for (j = 0;;) {
140 		x = random() % cols + 2;
141 		y = random() % lines + 2;
142 		cursor(x, y);
143 		fputchar('.');
144 		cursor(xpos[j], ypos[j]);
145 		fputchar('o');
146 		if (!j--)
147 			j = 4;
148 		cursor(xpos[j], ypos[j]);
149 		fputchar('O');
150 		if (!j--)
151 			j = 4;
152 		cursor(xpos[j], ypos[j] - 1);
153 		fputchar('-');
154 		tputs(DN, 1, fputchar);
155 		tputs(BC, 1, fputchar);
156 		tputs(BC, 1, fputchar);
157 		fputs("|.|", stdout);
158 		tputs(DN, 1, fputchar);
159 		tputs(BC, 1, fputchar);
160 		tputs(BC, 1, fputchar);
161 		fputchar('-');
162 		if (!j--)
163 			j = 4;
164 		cursor(xpos[j], ypos[j] - 2);
165 		fputchar('-');
166 		tputs(DN, 1, fputchar);
167 		tputs(BC, 1, fputchar);
168 		tputs(BC, 1, fputchar);
169 		fputs("/ \\", stdout);
170 		cursor(xpos[j] - 2, ypos[j]);
171 		fputs("| O |", stdout);
172 		cursor(xpos[j] - 1, ypos[j] + 1);
173 		fputs("\\ /", stdout);
174 		tputs(DN, 1, fputchar);
175 		tputs(BC, 1, fputchar);
176 		tputs(BC, 1, fputchar);
177 		fputchar('-');
178 		if (!j--)
179 			j = 4;
180 		cursor(xpos[j], ypos[j] - 2);
181 		fputchar(' ');
182 		tputs(DN, 1, fputchar);
183 		tputs(BC, 1, fputchar);
184 		tputs(BC, 1, fputchar);
185 		fputchar(' ');
186 		tputs(ND, 1, fputchar);
187 		fputchar(' ');
188 		cursor(xpos[j] - 2, ypos[j]);
189 		fputchar(' ');
190 		tputs(ND, 1, fputchar);
191 		fputchar(' ');
192 		tputs(ND, 1, fputchar);
193 		fputchar(' ');
194 		cursor(xpos[j] - 1, ypos[j] + 1);
195 		fputchar(' ');
196 		tputs(ND, 1, fputchar);
197 		fputchar(' ');
198 		tputs(DN, 1, fputchar);
199 		tputs(BC, 1, fputchar);
200 		tputs(BC, 1, fputchar);
201 		fputchar(' ');
202 		xpos[j] = x;
203 		ypos[j] = y;
204 		(void)fflush(stdout);
205 	}
206 }
207 
208 static
209 onsig()
210 {
211 	tputs(LL, 1, fputchar);
212 	if (TE)
213 		tputs(TE, 1, fputchar);
214 	(void)fflush(stdout);
215 #ifdef USG
216 	ioctl(1, TCSETAW, &old_tty);
217 #else
218 	stty(1, &old_tty);
219 #endif
220 	exit(0);
221 }
222 
223 static
224 fputchar(c)
225 	char c;
226 {
227 	putchar(c);
228 }
229