mv machine dependend from sys_process.c
[unix-history] / usr / src / games / worms / worms.c
CommitLineData
e0bbfbf9
DF
1#ifndef lint
2char copyright[] =
3"@(#) Copyright (c) 1980 Regents of the University of California.\n\
4 All rights reserved.\n";
5#endif not lint
5111e40b 6
e0bbfbf9 7#ifndef lint
4334b5fc 8static char sccsid[] = "@(#)worms.c 5.3 (Berkeley) %G%";
e0bbfbf9 9#endif not lint
5111e40b 10
4334b5fc
KM
11#define BSD
12
5111e40b
KM
13/*
14
15 @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
16 @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@
17 @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@
18 @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
19 @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@
20 @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@
21 @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@
22 @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@
23 @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@
24
25 Eric P. Scott
26 Caltech High Energy Physics
27 October, 1980
28
29*/
30#include <stdio.h>
4334b5fc
KM
31#ifdef USG
32#include <termio.h>
33#else
5111e40b 34#include <sgtty.h>
4334b5fc
KM
35#endif
36#include <signal.h>
37#define cursor(col,row) tputs(tgoto(CM,col,row),1,fputchar)
5111e40b
KM
38extern char *UP;
39extern short ospeed;
40int Wrap;
41short *ref[24];
42static char flavor[]={
43 'O', '*', '#', '$', '%', '0'
44};
45static short xinc[]={
46 1, 1, 1, 0, -1, -1, -1, 0
47}, yinc[]={
48 -1, 0, 1, 1, 1, 0, -1, -1
49};
50static struct worm {
51 int orientation, head;
52 short *xpos, *ypos;
53} worm[40];
54static char *field;
55static int length=16, number=3, trail=' ';
56static struct options {
57 int nopts;
58 int opts[3];
59} normal[8]={
60 { 3, { 7, 0, 1 } },
61 { 3, { 0, 1, 2 } },
62 { 3, { 1, 2, 3 } },
63 { 3, { 2, 3, 4 } },
64 { 3, { 3, 4, 5 } },
65 { 3, { 4, 5, 6 } },
66 { 3, { 5, 6, 7 } },
67 { 3, { 6, 7, 0 } }
68}, upper[8]={
69 { 1, { 1, 0, 0 } },
70 { 2, { 1, 2, 0 } },
71 { 0, { 0, 0, 0 } },
72 { 0, { 0, 0, 0 } },
73 { 0, { 0, 0, 0 } },
74 { 2, { 4, 5, 0 } },
75 { 1, { 5, 0, 0 } },
76 { 2, { 1, 5, 0 } }
77}, left[8]={
78 { 0, { 0, 0, 0 } },
79 { 0, { 0, 0, 0 } },
80 { 0, { 0, 0, 0 } },
81 { 2, { 2, 3, 0 } },
82 { 1, { 3, 0, 0 } },
83 { 2, { 3, 7, 0 } },
84 { 1, { 7, 0, 0 } },
85 { 2, { 7, 0, 0 } }
86}, right[8]={
87 { 1, { 7, 0, 0 } },
88 { 2, { 3, 7, 0 } },
89 { 1, { 3, 0, 0 } },
90 { 2, { 3, 4, 0 } },
91 { 0, { 0, 0, 0 } },
92 { 0, { 0, 0, 0 } },
93 { 0, { 0, 0, 0 } },
94 { 2, { 6, 7, 0 } }
95}, lower[8]={
96 { 0, { 0, 0, 0 } },
97 { 2, { 0, 1, 0 } },
98 { 1, { 1, 0, 0 } },
99 { 2, { 1, 5, 0 } },
100 { 1, { 5, 0, 0 } },
101 { 2, { 5, 6, 0 } },
102 { 0, { 0, 0, 0 } },
103 { 0, { 0, 0, 0 } }
104}, upleft[8]={
105 { 0, { 0, 0, 0 } },
106 { 0, { 0, 0, 0 } },
107 { 0, { 0, 0, 0 } },
108 { 0, { 0, 0, 0 } },
109 { 0, { 0, 0, 0 } },
110 { 1, { 3, 0, 0 } },
111 { 2, { 1, 3, 0 } },
112 { 1, { 1, 0, 0 } }
113}, upright[8]={
114 { 2, { 3, 5, 0 } },
115 { 1, { 3, 0, 0 } },
116 { 0, { 0, 0, 0 } },
117 { 0, { 0, 0, 0 } },
118 { 0, { 0, 0, 0 } },
119 { 0, { 0, 0, 0 } },
120 { 0, { 0, 0, 0 } },
121 { 1, { 5, 0, 0 } }
122}, lowleft[8]={
123 { 3, { 7, 0, 1 } },
124 { 0, { 0, 0, 0 } },
125 { 0, { 0, 0, 0 } },
126 { 1, { 1, 0, 0 } },
127 { 2, { 1, 7, 0 } },
128 { 1, { 7, 0, 0 } },
129 { 0, { 0, 0, 0 } },
130 { 0, { 0, 0, 0 } }
131}, lowright[8]={
132 { 0, { 0, 0, 0 } },
133 { 1, { 7, 0, 0 } },
134 { 2, { 5, 7, 0 } },
135 { 1, { 5, 0, 0 } },
136 { 0, { 0, 0, 0 } },
137 { 0, { 0, 0, 0 } },
138 { 0, { 0, 0, 0 } },
139 { 0, { 0, 0, 0 } }
140};
4334b5fc 141char *TE;
5111e40b
KM
142main(argc,argv)
143int argc;
144char *argv[];
145{
146 extern fputchar();
147 char *malloc();
148 char *getenv();
149 char *tgetstr(), *tgoto();
4334b5fc 150 int quit();
5111e40b
KM
151 float ranf();
152 register int x, y;
153 register int n;
154 register struct worm *w;
155 register struct options *op;
156 register int h;
157 register short *ip;
158 char *AL, *BC, *CM, *EI, *HO, *IC, *IM, *IP, *SR;
159 int CO, IN, LI, last, bottom;
160 char *tcp;
161 register char *term;
162 char tcb[100];
4334b5fc
KM
163#ifdef USG
164 struct termio sg;
165#else
5111e40b 166 struct sgttyb sg;
4334b5fc 167#endif
5111e40b
KM
168 setbuf(stdout,malloc(BUFSIZ));
169 for (x=1;x<argc;x++) {
170 register char *p;
171 p=argv[x];
172 if (*p=='-') p++;
173 switch (*p) {
174 case 'f':
175 field="WORM";
176 break;
177 case 'l':
178 if (++x==argc) goto usage;
179 if ((length=atoi(argv[x]))<2||length>1024) {
180 fprintf(stderr,"%s: Invalid length\n",*argv);
181 exit(1);
182 }
183 break;
184 case 'n':
185 if (++x==argc) goto usage;
186 if ((number=atoi(argv[x]))<1||number>40) {
187 fprintf(stderr,"%s: Invalid number of worms\n",*argv);
188 exit(1);
189 }
190 break;
191 case 't':
192 trail='.';
193 break;
194 default:
195 usage:
196 fprintf(stderr,
197 "usage: %s [-field] [-length #] [-number #] [-trail]\n",*argv);
198 exit(1);
199 break;
200 }
201 }
202 if (!(term=getenv("TERM"))) {
203 fprintf(stderr,"%s: TERM: parameter not set\n",*argv);
204 exit(1);
205 }
206 if (tgetent(malloc(1024),term)<=0) {
207 fprintf(stderr,"%s: %s: unknown terminal type\n",*argv,term);
208 exit(1);
209 }
210 tcp=tcb;
211 if (!(CM=tgetstr("cm",&tcp))) {
212 fprintf(stderr,"%s: terminal not capable of cursor motion\n",*argv);
213 exit(1);
214 }
215 AL=tgetstr("al",&tcp);
216 BC=tgetflag("bs") ? "\b" : tgetstr("bc",&tcp);
217 if ((CO=tgetnum("co"))<=0) CO=80;
218 last=CO-1;
219 EI=tgetstr("ei",&tcp);
220 HO=tgetstr("ho",&tcp);
221 IC=tgetstr("ic",&tcp);
222 IM=tgetstr("im",&tcp);
223 IN=tgetflag("in");
224 IP=tgetstr("ip",&tcp);
225 if ((LI=tgetnum("li"))<=0) LI=24;
226 bottom=LI-1;
227 SR=tgetstr("sr",&tcp);
4334b5fc 228 TE=tgetstr("te",&tcp);
5111e40b 229 UP=tgetstr("up",&tcp);
4334b5fc
KM
230#ifdef USG
231 ioctl(fileno(stdout),TCGETA,&sg);
232 ospeed=sg.c_cflag&CBAUD;
233#else
5111e40b
KM
234 gtty(fileno(stdout),&sg);
235 ospeed=sg.sg_ospeed;
4334b5fc 236#endif
5111e40b
KM
237 Wrap=tgetflag("am");
238 ip=(short *)malloc(LI*CO*sizeof (short));
239 for (n=0;n<LI;) {
240 ref[n++]=ip; ip+=CO;
241 }
242 for (ip=ref[0],n=LI*CO;--n>=0;) *ip++=0;
243 if (Wrap) ref[bottom][last]=1;
244 for (n=number, w= &worm[0];--n>=0;w++) {
245 w->orientation=w->head=0;
246 if (!(ip=(short *)malloc(length*sizeof (short)))) {
247 fprintf(stderr,"%s: out of memory\n",*argv);
248 exit(1);
249 }
250 w->xpos=ip;
251 for (x=length;--x>=0;) *ip++ = -1;
252 if (!(ip=(short *)malloc(length*sizeof (short)))) {
253 fprintf(stderr,"%s: out of memory\n",*argv);
254 exit(1);
255 }
256 w->ypos=ip;
257 for (y=length;--y>=0;) *ip++ = -1;
258 }
4334b5fc
KM
259 signal(SIGINT, quit);
260 tputs(tgetstr("ti",&tcp),1,fputchar);
5111e40b
KM
261 tputs(tgetstr("cl",&tcp),1,fputchar);
262 if (field) {
263 register char *p;
264 p=field;
265 for (y=bottom;--y>=0;) {
266 for (x=CO;--x>=0;) {
267 putchar(*p++);
268 if (!*p) p=field;
269 }
270 if (!Wrap) putchar('\n');
271 fflush(stdout);
272 }
273 if (Wrap) {
274 if (IM&&!IN) {
275 for (x=last;--x>0;) {
276 putchar(*p++);
277 if (!*p) p=field;
278 }
279 y= *p++; if (!*p) p=field;
280 putchar(*p);
4334b5fc 281 if (BC) tputs(BC,1,fputchar);
5111e40b 282 else cursor(last-1,bottom);
4334b5fc 283 tputs(IM,1,fputchar);
5111e40b
KM
284 if (IC) tputs(IC,1,fputchar);
285 putchar(y);
286 if (IP) tputs(IP,1,fputchar);
4334b5fc 287 tputs(EI,1,fputchar);
5111e40b
KM
288 }
289 else if (SR||AL) {
4334b5fc 290 if (HO) tputs(HO,1,fputchar);
5111e40b
KM
291 else cursor(0,0);
292 if (SR) tputs(SR,1,fputchar);
293 else tputs(AL,LI,fputchar);
294 for (x=CO;--x>=0;) {
295 putchar(*p++);
296 if (!*p) p=field;
297 }
298 }
299 else for (x=last;--x>=0;) {
300 putchar(*p++);
301 if (!*p) p=field;
302 }
303 }
304 else for (x=CO;--x>=0;) {
305 putchar(*p++);
306 if (!*p) p=field;
307 }
308 }
309 fflush(stdout);
310 for (;;) {
311 for (n=0,w= &worm[0];n<number;n++,w++) {
312 if ((x=w->xpos[h=w->head])<0) {
313 cursor(x=w->xpos[h]=0,y=w->ypos[h]=bottom);
314 putchar(flavor[n%6]);
315 ref[y][x]++;
316 }
317 else y=w->ypos[h];
318 if (++h==length) h=0;
319 if (w->xpos[w->head=h]>=0) {
320 register int x1, y1;
321 x1=w->xpos[h]; y1=w->ypos[h];
322 if (--ref[y1][x1]==0) {
323 cursor(x1,y1); putchar(trail);
324 }
325 }
326 op= &(x==0 ? (y==0 ? upleft : (y==bottom ? lowleft : left)) :
327 (x==last ? (y==0 ? upright : (y==bottom ? lowright : right)) :
328 (y==0 ? upper : (y==bottom ? lower : normal))))[w->orientation];
329 switch (op->nopts) {
330 case 0:
331 fflush(stdout);
332 abort();
333 return;
334 case 1:
335 w->orientation=op->opts[0];
336 break;
337 default:
338 w->orientation=op->opts[(int)(ranf()*(float)op->nopts)];
339 }
340 cursor(x+=xinc[w->orientation], y+=yinc[w->orientation]);
341 if (!Wrap||x!=last||y!=bottom) putchar(flavor[n%6]);
342 ref[w->ypos[h]=y][w->xpos[h]=x]++;
343 }
344 fflush(stdout);
345 }
346}
4334b5fc
KM
347quit()
348{
349 signal(SIGINT, SIG_IGN);
350 tputs(TE,1,fputchar);
351 exit(0);
352}
5111e40b
KM
353fputchar(c)
354char c;
355{
356 putchar(c);
357}
358float ranf() {
4334b5fc 359#ifdef BSD
5111e40b 360 return((float)rand()/2147483647.);
4334b5fc
KM
361#else
362 return((float)rand()/32767.);
363#endif
5111e40b 364}