X-Git-Url: https://git.cameronkatri.com/bsdgames-darwin.git/blobdiff_plain/77e3814f0c0e3dea4d0032e25666f77e6f83bfff..4c76b7ec11ea4a4c4f121d6623ddec249e227899:/worm/worm.c diff --git a/worm/worm.c b/worm/worm.c index 65a7423b..2c166128 100644 --- a/worm/worm.c +++ b/worm/worm.c @@ -1,6 +1,8 @@ +/* $NetBSD: worm.c,v 1.28 2008/08/08 16:10:47 drochner Exp $ */ + /* - * Copyright (c) 1980 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -31,14 +29,18 @@ * SUCH DAMAGE. */ +#include #ifndef lint -char copyright[] = -"@(#) Copyright (c) 1980 Regents of the University of California.\n\ - All rights reserved.\n"; +__COPYRIGHT("@(#) Copyright (c) 1980, 1993\ + The Regents of the University of California. All rights reserved."); #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)worm.c 5.8 (Berkeley) 2/28/91"; +#if 0 +static char sccsid[] = "@(#)worm.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: worm.c,v 1.28 2008/08/08 16:10:47 drochner Exp $"); +#endif #endif /* not lint */ /* @@ -48,19 +50,18 @@ static char sccsid[] = "@(#)worm.c 5.8 (Berkeley) 2/28/91"; #include #include +#include #include +#include +#include +#include #define newlink() (struct body *) malloc(sizeof (struct body)); #define HEAD '@' #define BODY 'o' #define LENGTH 7 #define RUNLEN 8 -#define when break;case -#define otherwise break;default #define CNTRL(p) (p-'A'+1) -#ifndef baudrate -# define baudrate() _tty.sg_ospeed -#endif WINDOW *tv; WINDOW *stw; @@ -75,32 +76,58 @@ int running = 0; int slow = 0; int score = 0; int start_len = LENGTH; -char lastch; +int visible_len; +int lastch; char outbuf[BUFSIZ]; -void leave(), wake(), suspend(); +void crash(void) __dead; +void display(const struct body *, char); +int main(int, char **); +void leave(int) __dead; +void life(void); +void newpos(struct body *); +void process(int); +void prize(void); +int rnd(int); +void setup(void); +void wake(int); +int main(argc, argv) int argc; char **argv; { - char ch; - if (argc == 2) - start_len = atoi(argv[1]); - if ((start_len <= 0) || (start_len > 500)) - start_len = LENGTH; + /* Revoke setgid privileges */ + setgid(getgid()); + setbuf(stdout, outbuf); srand(getpid()); signal(SIGALRM, wake); signal(SIGINT, leave); signal(SIGQUIT, leave); - signal(SIGTSTP, suspend); /* process control signal */ - initscr(); - crmode(); + if (!initscr()) + errx(0, "couldn't initialize screen"); + cbreak(); noecho(); - slow = (baudrate() <= B1200); +#ifdef KEY_LEFT + keypad(stdscr, TRUE); +#endif + slow = (baudrate() <= 1200); clear(); + if (COLS < 18 || LINES < 5) { + /* + * Insufficient room for the line with " Worm" and the + * score if fewer than 18 columns; insufficient room for + * anything much if fewer than 5 lines. + */ + endwin(); + errx(1, "screen too small"); + } + if (argc == 2) + start_len = atoi(argv[1]); + if ((start_len <= 0) || (start_len > ((LINES-3) * (COLS-2)) / 3)) + start_len = LENGTH; stw = newwin(1, COLS-1, 0, 0); tv = newwin(LINES-1, COLS-1, 1, 0); box(tv, '*', '*'); @@ -123,72 +150,103 @@ main(argc, argv) else { fflush(stdout); - if (read(0, &ch, 1) >= 0) - process(ch); + process(getch()); } } } +void life() { - register struct body *bp, *np; - register int i; + struct body *bp, *np; + int i, j = 1; + np = NULL; head = newlink(); - head->x = start_len+2; - head->y = 12; + if (head == NULL) + err(1, NULL); + head->x = start_len % (COLS-5) + 2; + head->y = LINES / 2; head->next = NULL; display(head, HEAD); for (i = 0, bp = head; i < start_len; i++, bp = np) { np = newlink(); + if (np == NULL) + err(1, NULL); np->next = bp; bp->prev = np; - np->x = bp->x - 1; - np->y = bp->y; + if (((bp->x <= 2) && (j == 1)) || ((bp->x >= COLS-4) && (j == -1))) { + j *= -1; + np->x = bp->x; + np->y = bp->y + 1; + } else { + np->x = bp->x - j; + np->y = bp->y; + } display(np, BODY); } tail = np; tail->prev = NULL; + visible_len = start_len + 1; } +void display(pos, chr) -struct body *pos; -char chr; + const struct body *pos; + char chr; { wmove(tv, pos->y, pos->x); waddch(tv, chr); } void -leave() +leave(dummy) + int dummy; { endwin(); + + if (dummy == 0){ /* called via crash() */ + printf("\nWell, you ran into something and the game is over.\n"); + printf("Your final score was %d\n\n", score); + } exit(0); } void -wake() +wake(dummy) + int dummy __unused; { signal(SIGALRM, wake); fflush(stdout); process(lastch); } +int rnd(range) + int range; { return abs((rand()>>5)+(rand()>>5)) % range; } +void newpos(bp) -struct body * bp; + struct body * bp; { + if (visible_len == (LINES-3) * (COLS-3) - 1) { + endwin(); + + printf("\nYou won!\n"); + printf("Your final score was %d\n\n", score); + exit(0); + } do { - bp->y = rnd(LINES-3)+ 2; + bp->y = rnd(LINES-3)+ 1; bp->x = rnd(COLS-3) + 1; wmove(tv, bp->y, bp->x); } while(winch(tv) != ' '); } +void prize() { int value; @@ -199,10 +257,11 @@ prize() wrefresh(tv); } +void process(ch) -char ch; + int ch; { - register int x,y; + int x,y; struct body *nh; alarm(0); @@ -210,19 +269,43 @@ char ch; y = head->y; switch(ch) { - when 'h': x--; - when 'j': y++; - when 'k': y--; - when 'l': x++; - when 'H': x--; running = RUNLEN; ch = tolower(ch); - when 'J': y++; running = RUNLEN/2; ch = tolower(ch); - when 'K': y--; running = RUNLEN/2; ch = tolower(ch); - when 'L': x++; running = RUNLEN; ch = tolower(ch); - when '\f': setup(); return; - when CNTRL('Z'): suspend(); return; - when CNTRL('C'): crash(); return; - when CNTRL('D'): crash(); return; - otherwise: if (! running) alarm(1); +#ifdef KEY_LEFT + case KEY_LEFT: +#endif + case 'h': + x--; break; + +#ifdef KEY_DOWN + case KEY_DOWN: +#endif + case 'j': + y++; break; + +#ifdef KEY_UP + case KEY_UP: +#endif + case 'k': + y--; break; + +#ifdef KEY_RIGHT + case KEY_RIGHT: +#endif + case 'l': + x++; break; + + case 'H': x--; running = RUNLEN; ch = tolower(ch); break; + case 'J': y++; running = RUNLEN/2; ch = tolower(ch); break; + case 'K': y--; running = RUNLEN/2; ch = tolower(ch); break; + case 'L': x++; running = RUNLEN; ch = tolower(ch); break; + case '\f': setup(); return; + + case ERR: + case CNTRL('C'): + case CNTRL('D'): + crash(); + return; + + default: if (! running) alarm(1); return; } lastch = ch; @@ -233,6 +316,7 @@ char ch; nh = tail->next; free(tail); tail = nh; + visible_len--; } else growing--; display(head, BODY); @@ -243,12 +327,14 @@ char ch; prize(); score += growing; running = 0; - wmove(stw, 0, 68); + wmove(stw, 0, COLS - 12); wprintw(stw, "Score: %3d", score); wrefresh(stw); } else if(ch != ' ') crash(); nh = newlink(); + if (nh == NULL) + err(1, NULL); nh->next = NULL; nh->prev = head; head->next = nh; @@ -256,39 +342,23 @@ char ch; nh->x = x; display(nh, HEAD); head = nh; + visible_len++; if (!(slow && running)) + { + wmove(tv, head->y, head->x); wrefresh(tv); + } if (!running) alarm(1); } +void crash() { - sleep(2); - clear(); - move(23, 0); - refresh(); - printf("Well, you ran into something and the game is over.\n"); - printf("Your final score was %d\n", score); - leave(); + leave(0); } void -suspend() -{ - char *sh; - - move(LINES-1, 0); - refresh(); - endwin(); - fflush(stdout); - kill(getpid(), SIGTSTP); - signal(SIGTSTP, suspend); - crmode(); - noecho(); - setup(); -} - setup() { clear();