]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - worm/worm.c
bogus lseek extern
[bsdgames-darwin.git] / worm / worm.c
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, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 char copyright[] =
36 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
37 All rights reserved.\n";
38 #endif /* not lint */
39
40 #ifndef lint
41 /*static char sccsid[] = "from: @(#)worm.c 5.8 (Berkeley) 2/28/91";*/
42 static char rcsid[] = "$Id: worm.c,v 1.4 1993/12/03 10:12:57 mycroft Exp $";
43 #endif /* not lint */
44
45 /*
46 * Worm. Written by Michael Toy
47 * UCSC
48 */
49
50 #include <ctype.h>
51 #include <curses.h>
52 #include <signal.h>
53
54 #define newlink() (struct body *) malloc(sizeof (struct body));
55 #define HEAD '@'
56 #define BODY 'o'
57 #define LENGTH 7
58 #define RUNLEN 8
59 #define CNTRL(p) (p-'A'+1)
60 #ifndef baudrate
61 # define baudrate() _tty.sg_ospeed
62 #endif
63
64 WINDOW *tv;
65 WINDOW *stw;
66 struct body {
67 int x;
68 int y;
69 struct body *prev;
70 struct body *next;
71 } *head, *tail, goody;
72 int growing = 0;
73 int running = 0;
74 int slow = 0;
75 int score = 0;
76 int start_len = LENGTH;
77 char lastch;
78 char outbuf[BUFSIZ];
79
80 void leave(), wake(), suspend();
81
82 main(argc, argv)
83 int argc;
84 char **argv;
85 {
86 char ch;
87
88 if (argc == 2)
89 start_len = atoi(argv[1]);
90 if ((start_len <= 0) || (start_len > 500))
91 start_len = LENGTH;
92 setbuf(stdout, outbuf);
93 srand(getpid());
94 signal(SIGALRM, wake);
95 signal(SIGINT, leave);
96 signal(SIGQUIT, leave);
97 signal(SIGTSTP, suspend); /* process control signal */
98 initscr();
99 crmode();
100 noecho();
101 slow = (baudrate() <= 1200);
102 clear();
103 stw = newwin(1, COLS-1, 0, 0);
104 tv = newwin(LINES-1, COLS-1, 1, 0);
105 box(tv, '*', '*');
106 scrollok(tv, FALSE);
107 scrollok(stw, FALSE);
108 wmove(stw, 0, 0);
109 wprintw(stw, " Worm");
110 refresh();
111 wrefresh(stw);
112 wrefresh(tv);
113 life(); /* Create the worm */
114 prize(); /* Put up a goal */
115 while(1)
116 {
117 if (running)
118 {
119 running--;
120 process(lastch);
121 }
122 else
123 {
124 fflush(stdout);
125 if (read(0, &ch, 1) >= 0)
126 process(ch);
127 }
128 }
129 }
130
131 life()
132 {
133 register struct body *bp, *np;
134 register int i;
135
136 head = newlink();
137 head->x = start_len+2;
138 head->y = 12;
139 head->next = NULL;
140 display(head, HEAD);
141 for (i = 0, bp = head; i < start_len; i++, bp = np) {
142 np = newlink();
143 np->next = bp;
144 bp->prev = np;
145 np->x = bp->x - 1;
146 np->y = bp->y;
147 display(np, BODY);
148 }
149 tail = np;
150 tail->prev = NULL;
151 }
152
153 display(pos, chr)
154 struct body *pos;
155 char chr;
156 {
157 wmove(tv, pos->y, pos->x);
158 waddch(tv, chr);
159 }
160
161 void
162 leave()
163 {
164 endwin();
165 exit(0);
166 }
167
168 void
169 wake()
170 {
171 signal(SIGALRM, wake);
172 fflush(stdout);
173 process(lastch);
174 }
175
176 rnd(range)
177 {
178 return abs((rand()>>5)+(rand()>>5)) % range;
179 }
180
181 newpos(bp)
182 struct body * bp;
183 {
184 do {
185 bp->y = rnd(LINES-3)+ 2;
186 bp->x = rnd(COLS-3) + 1;
187 wmove(tv, bp->y, bp->x);
188 } while(winch(tv) != ' ');
189 }
190
191 prize()
192 {
193 int value;
194
195 value = rnd(9) + 1;
196 newpos(&goody);
197 waddch(tv, value+'0');
198 wrefresh(tv);
199 }
200
201 process(ch)
202 char ch;
203 {
204 register int x,y;
205 struct body *nh;
206
207 alarm(0);
208 x = head->x;
209 y = head->y;
210 switch(ch)
211 {
212 case 'h': x--; break;
213 case 'j': y++; break;
214 case 'k': y--; break;
215 case 'l': x++; break;
216 case 'H': x--; running = RUNLEN; ch = tolower(ch); break;
217 case 'J': y++; running = RUNLEN/2; ch = tolower(ch); break;
218 case 'K': y--; running = RUNLEN/2; ch = tolower(ch); break;
219 case 'L': x++; running = RUNLEN; ch = tolower(ch); break;
220 case '\f': setup(); return;
221 case CNTRL('Z'): suspend(); return;
222 case CNTRL('C'): crash(); return;
223 case CNTRL('D'): crash(); return;
224 default: if (! running) alarm(1);
225 return;
226 }
227 lastch = ch;
228 if (growing == 0)
229 {
230 display(tail, ' ');
231 tail->next->prev = NULL;
232 nh = tail->next;
233 free(tail);
234 tail = nh;
235 }
236 else growing--;
237 display(head, BODY);
238 wmove(tv, y, x);
239 if (isdigit(ch = winch(tv)))
240 {
241 growing += ch-'0';
242 prize();
243 score += growing;
244 running = 0;
245 wmove(stw, 0, 68);
246 wprintw(stw, "Score: %3d", score);
247 wrefresh(stw);
248 }
249 else if(ch != ' ') crash();
250 nh = newlink();
251 nh->next = NULL;
252 nh->prev = head;
253 head->next = nh;
254 nh->y = y;
255 nh->x = x;
256 display(nh, HEAD);
257 head = nh;
258 if (!(slow && running))
259 wrefresh(tv);
260 if (!running)
261 alarm(1);
262 }
263
264 crash()
265 {
266 sleep(2);
267 clear();
268 move(23, 0);
269 refresh();
270 printf("Well, you ran into something and the game is over.\n");
271 printf("Your final score was %d\n", score);
272 leave();
273 }
274
275 void
276 suspend()
277 {
278 char *sh;
279
280 move(LINES-1, 0);
281 refresh();
282 endwin();
283 fflush(stdout);
284 kill(getpid(), SIGTSTP);
285 signal(SIGTSTP, suspend);
286 crmode();
287 noecho();
288 setup();
289 }
290
291 setup()
292 {
293 clear();
294 refresh();
295 touchwin(stw);
296 wrefresh(stw);
297 touchwin(tv);
298 wrefresh(tv);
299 alarm(1);
300 }