diff options
author | jsm <jsm@NetBSD.org> | 1999-09-14 18:07:21 +0000 |
---|---|---|
committer | jsm <jsm@NetBSD.org> | 1999-09-14 18:07:21 +0000 |
commit | d2e32fbfdf35f7c638077852aa6fd4f772e565c8 (patch) | |
tree | c045523b5ebd943bfa0749ccd78b6a2dcde5e8a8 /snake/snake/move.c | |
parent | 30048bed36996889f3fd51086cd36dc9e67a1808 (diff) | |
download | bsdgames-darwin-d2e32fbfdf35f7c638077852aa6fd4f772e565c8.tar.gz bsdgames-darwin-d2e32fbfdf35f7c638077852aa6fd4f772e565c8.tar.zst bsdgames-darwin-d2e32fbfdf35f7c638077852aa6fd4f772e565c8.zip |
Convert snake to use curses, and generally clean it up somewhat.
Includes bugfixes from or inspired by OpenBSD.
Diffstat (limited to 'snake/snake/move.c')
-rw-r--r-- | snake/snake/move.c | 712 |
1 files changed, 0 insertions, 712 deletions
diff --git a/snake/snake/move.c b/snake/snake/move.c deleted file mode 100644 index 2308aeb5..00000000 --- a/snake/snake/move.c +++ /dev/null @@ -1,712 +0,0 @@ -/* $NetBSD: move.c,v 1.17 1999/09/08 21:17:59 jsm Exp $ */ - -/* - * 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 - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 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 - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 7/19/93"; -#else -__RCSID("$NetBSD: move.c,v 1.17 1999/09/08 21:17:59 jsm Exp $"); -#endif -#endif /* not lint */ - -/************************************************************************* - * - * MOVE LIBRARY - * - * This set of subroutines moves a cursor to a predefined - * location, independent of the terminal type. If the - * terminal has an addressable cursor, it uses it. If - * not, it optimizes for tabs (currently) even if you don't - * have them. - * - * At all times the current address of the cursor must be maintained, - * and that is available as structure cursor. - * - * The following calls are allowed: - * move(sp) move to point sp. - * up() move up one line. - * down() move down one line. - * bs() move left one space (except column 0). - * nd() move right one space(no write). - * clear() clear screen. - * home() home. - * ll() move to lower left corner of screen. - * cr() carriage return (no line feed). - * pr() just like standard printf, but keeps track - * of cursor position. (Uses pstring). - * apr() same as printf, but first argument is &point. - * (Uses pstring). - * pstring(s) output the string of printing characters. - * However, '\r' is interpreted to mean return - * to column of origination AND do linefeed. - * '\n' causes <cr><lf>. - * putpad(str) calls tputs to output character with proper - * padding. - * outch() the output routine for a character used by - * tputs. It just calls putchar. - * pch(ch) output character to screen and update - * cursor address (must be a standard - * printing character). WILL SCROLL. - * pchar(ps,ch) prints one character if it is on the - * screen at the specified location; - * otherwise, dumps it.(no wrap-around). - * - * getcap() initializes strings for later calls. - * cap(string) outputs the string designated in the termcap - * data base. (Should not move the cursor.) - * done() returns the terminal to intial state and exits. - * - * point(&p,x,y) return point set to x,y. - * - * delay(t) causes an approximately constant delay - * independent of baudrate. - * Duration is ~ t/20 seconds. - * - ******************************************************************************/ - -#if __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include "snake.h" - -int CMlength; -int NDlength; -int BSlength; -int delaystr[10]; -short ospeed; - -static char str[80]; - -void -move(sp) - struct point *sp; -{ - int distance; - int tabcol, ct; - struct point z; - - if (sp->line < 0 || sp->col < 0 || sp->col > COLUMNS) { - pr("move to [%d,%d]?", sp->line, sp->col); - return; - } - if (sp->line >= LINES) { - move(point(&z, sp->col, LINES - 1)); - while (sp->line-- >= LINES) - putchar('\n'); - return; - } - if (CM != 0) { - char *cmstr = tgoto(CM, sp->col, sp->line); - - CMlength = strlen(cmstr); - if (cursor.line == sp->line) { - distance = sp->col - cursor.col; - if (distance == 0) - return; /* Already there! */ - if (distance > 0) { /* Moving to the right */ - if (distance * NDlength < CMlength) { - right(sp); - return; - } - if (TA) { - ct = sp->col & 7; - tabcol = (cursor.col | 7) + 1; - do { - ct++; - tabcol = (tabcol | 7) + 1; - } - while (tabcol < sp->col); - if (ct < CMlength) { - right(sp); - return; - } - } - } else {/* Moving to the left */ - if (-distance * BSlength < CMlength) { - gto(sp); - return; - } - } - if (sp->col < CMlength) { - cr(); - right(sp); - return; - } - /* No more optimizations on same row. */ - } - distance = sp->col - cursor.col; - distance = distance > 0 ? - distance * NDlength : -distance * BSlength; - if (distance < 0) - pr("ERROR: distance is negative: %d", distance); - distance += abs(sp->line - cursor.line); - if (distance >= CMlength) { - putpad(cmstr); - cursor.line = sp->line; - cursor.col = sp->col; - return; - } - } - /* - * If we get here we have a terminal that can't cursor - * address but has local motions or one which can cursor - * address but can get there quicker with local motions. - */ - gto(sp); -} - -void -gto(sp) - const struct point *sp; -{ - - int distance, f, tfield; - - if (cursor.line > LINES || cursor.line < 0 || - cursor.col < 0 || cursor.col > COLUMNS) - pr("ERROR: cursor is at %d,%d\n", - cursor.line, cursor.col); - if (sp->line > LINES || sp->line < 0 || - sp->col < 0 || sp->col > COLUMNS) - pr("ERROR: target is %d,%d\n", sp->line, sp->col); - tfield = (sp->col) >> 3; - if (sp->line == cursor.line) { - if (sp->col > cursor.col) - right(sp); - else { - distance = (cursor.col - sp->col) * BSlength; - if (((TA) && - (distance > tfield + ((sp->col) & 7) * NDlength) - ) || - (((cursor.col) * NDlength) < distance) - ) { - cr(); - right(sp); - } else { - while (cursor.col > sp->col) - bs(); - } - } - return; - } - /* must change row */ - if (cursor.col - sp->col > (cursor.col >> 3)) { - if (cursor.col == 0) - f = 0; - else - f = -1; - } else - f = cursor.col >> 3; - if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)) { - /* - * home quicker than rlf: - * (sp->line + f > cursor.line - sp->line) - */ - putpad(HO); - cursor.col = cursor.line = 0; - gto(sp); - return; - } - if (((sp->line << 1) > cursor.line + LINES + 1 + f) && (LL != 0)) { - /* home,rlf quicker than lf (LINES+1 - sp->line + f < sp->line - * - cursor.line) */ - if (cursor.line > f + 1) { - /* is home faster than wraparound lf? (cursor.line + - * 20 - sp->line > 21 - sp->line + f) */ - ll(); - gto(sp); - return; - } - } - if ((LL != 0) && (sp->line > cursor.line + (LINES >> 1) - 1)) - cursor.line += LINES; - while (sp->line > cursor.line) - down(); - while (sp->line < cursor.line) - up(); - gto(sp); /* can recurse since cursor.line = sp->line */ -} - -void -right(sp) - const struct point *sp; -{ - int field, tfield; - int tabcol, strlength; - - if (sp->col < cursor.col) - pr("ERROR:right() can't move left\n"); - if (TA) { /* If No Tabs: can't send tabs because - * ttydrive loses count with control - * characters. */ - field = cursor.col >> 3; -/* - * This code is useful for a terminal which wraps around on backspaces. - * (Mine does.) Unfortunately, this is not specified in termcap, and - * most terminals don't work that way. (Of course, most terminals - * have addressible cursors, too). - */ - if (BW && (CM == 0) && - ((sp->col << 1) - field > (COLUMNS - 8) << 1) - ) { - if (cursor.line == 0) { - outch('\n'); - } - outch('\r'); - cursor.col = COLUMNS + 1; - while (cursor.col > sp->col) - bs(); - if (cursor.line != 0) - outch('\n'); - return; - } - tfield = sp->col >> 3; - - while (field < tfield) { - putpad(TA); - cursor.col = ++field << 3; - } - tabcol = (cursor.col | 7) + 1; - strlength = (tabcol - sp->col) * BSlength + 1; - /* length of sequence to overshoot */ - if (((sp->col - cursor.col) * NDlength > strlength) && - (tabcol < COLUMNS) - ) { - /* - * Tab past and backup - */ - putpad(TA); - cursor.col = (cursor.col | 7) + 1; - while (cursor.col > sp->col) - bs(); - } - } - while (sp->col > cursor.col) { - nd(); - } -} - -void -cr() -{ - outch('\r'); - cursor.col = 0; -} - -void -clear() -{ - int i; - - if (CL) { - putpad(CL); - cursor.col = cursor.line = 0; - } else { - for (i = 0; i < LINES; i++) { - putchar('\n'); - } - cursor.line = LINES - 1; - home(); - } -} - - -void -home() -{ - struct point z; - - if (HO != 0) { - putpad(HO); - cursor.col = cursor.line = 0; - return; - } - z.col = z.line = 0; - move(&z); -} - -void -ll() -{ - int l; - struct point z; - - l = lcnt + 2; - if (LL != NULL && LINES == l) { - putpad(LL); - cursor.line = LINES - 1; - cursor.col = 0; - return; - } - z.col = 0; - z.line = l - 1; - move(&z); -} - -void -up() -{ - putpad(UP); - cursor.line--; -} - -void -down() -{ - putpad(DO); - cursor.line++; - if (cursor.line >= LINES) - cursor.line = LINES - 1; -} - -void -bs() -{ - if (cursor.col > 0) { - putpad(BS); - cursor.col--; - } -} - -void -nd() -{ - putpad(ND); - cursor.col++; - if (cursor.col == COLUMNS + 1) { - cursor.line++; - cursor.col = 0; - if (cursor.line >= LINES) - cursor.line = LINES - 1; - } -} - -void -pch(c) - int c; -{ - outch(c); - if (++cursor.col >= COLUMNS && AM) { - cursor.col = 0; - ++cursor.line; - } -} - -void -#if __STDC__ -apr(const struct point * ps, const char *fmt,...) -#else -apr(ps, fmt, va_alist) - const struct point *ps; - char *fmt; -va_dcl -#endif -{ - struct point p; - va_list ap; - - p.line = ps->line + 1; - p.col = ps->col + 1; - move(&p); -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - (void) vsprintf(str, fmt, ap); - va_end(ap); - pstring(str); -} - -void -#if __STDC__ -pr(const char *fmt,...) -#else -pr(fmt, va_alist) - char *fmt; -va_dcl -#endif -{ - va_list ap; - -#if __STDC__ - va_start(ap, fmt); -#else - va_start(ap); -#endif - (void) vsprintf(str, fmt, ap); - va_end(ap); - pstring(str); -} - -void -pstring(s) - const char *s; -{ - struct point z; - int stcol; - - stcol = cursor.col; - while (s[0] != '\0') { - switch (s[0]) { - case '\n': - move(point(&z, 0, cursor.line + 1)); - break; - case '\r': - move(point(&z, stcol, cursor.line + 1)); - break; - case '\t': - z.col = (((cursor.col + 8) >> 3) << 3); - z.line = cursor.line; - move(&z); - break; - case '\b': - bs(); - break; - case CTRL('g'): - outch(CTRL('g')); - break; - default: - if (s[0] < ' ') - break; - pch(s[0]); - } - s++; - } -} - -void -pchar(ps, ch) - const struct point *ps; - char ch; -{ - struct point p; - p.col = ps->col + 1; - p.line = ps->line + 1; - if ( - (p.col >= 0) && - (p.line >= 0) && - ( - ( - (p.line < LINES) && - (p.col < COLUMNS) - ) || - ( - (p.col == COLUMNS) && - (p.line < LINES - 1) - ) - ) - ) { - move(&p); - pch(ch); - } -} - -void -outch(c) - int c; -{ - putchar(c); -} - -void -putpad(str) - const char *str; -{ - if (str) - tputs(str, 1, outch); -} - -void -delay(t) - int t; -{ - int k, j; - - k = (ospeed * t + 100) / 200; - for (j = 0; j < k; j++) { - putchar(PC); - } -} - -void -done() -{ - cook(); - exit(0); -} - -void -cook() -{ - delay(1); - putpad(TE); - putpad(KE); - fflush(stdout); - tcsetattr(0, TCSADRAIN, &orig); -} - -void -raw() -{ - tcsetattr(0, TCSADRAIN, &new); -} - -struct point * -point(ps, x, y) - struct point *ps; - int x, y; -{ - ps->col = x; - ps->line = y; - return (ps); -} - -char *ap; - -void -getcap() -{ - char *term; - char *xPC; -#ifdef TIOCGWINSZ - struct winsize win; -#endif - - term = getenv("TERM"); - if (term == 0) - errx(1, "No TERM in environment"); - switch (tgetent(tbuf, term)) { - case -1: - errx(2, "Cannot open termcap file"); - case 0: - errx(3, "unknown terminal `%s'", term); - } - - ap = tcapbuf; - -#ifdef TIOCGWINSZ - if (ioctl(0, TIOCGWINSZ, (char *) &win) < 0 || - (LINES = win.ws_row) == 0 || (COLUMNS = win.ws_col) == 0) { -#endif - LINES = tgetnum("li"); - COLUMNS = tgetnum("co"); -#ifdef TIOCGWINSZ - } -#endif - if (!lcnt) - lcnt = LINES - 2; - if (!ccnt) - ccnt = COLUMNS - 3; - - AM = tgetflag("am"); - BW = tgetflag("bw"); - - ND = tgetstr("nd", &ap); - UP = tgetstr("up", &ap); - - DO = tgetstr("do", &ap); - if (DO == 0) - DO = "\n"; - - BS = tgetstr("le", &ap); - if (BS == 0) { - /* try using obsolete capabilities */ - BS = tgetstr("bc", &ap); - if (BS == 0 && tgetflag("bs")) - BS = "\b"; - } - TA = tgetstr("ta", &ap); - if (TA == 0 && tgetflag("pt")) - TA = "\t"; - - HO = tgetstr("ho", &ap); - CL = tgetstr("cl", &ap); - CM = tgetstr("cm", &ap); - LL = tgetstr("ll", &ap); - - KL = tgetstr("kl", &ap); - KR = tgetstr("kr", &ap); - KU = tgetstr("ku", &ap); - KD = tgetstr("kd", &ap); - if (KL && KR && KU && KD) - Klength = strlen(KL); - else - Klength = 0; - /* NOTE: If KL, KR, KU, and KD are not all the same length, some - * problems may arise, since tests are made on all of them together. */ - - TI = tgetstr("ti", &ap); - TE = tgetstr("te", &ap); - KS = tgetstr("ks", &ap); - KE = tgetstr("ke", &ap); - - xPC = tgetstr("pc", &ap); - if (xPC) - PC = *xPC; - - if ((CM == 0) && - (HO == 0 || UP == 0 || BS == 0 || ND == 0)) - errx(5, "Terminal must have addressible cursor or home + 4 local motions"); - if (ND == 0) - errx(5, "Terminal must have `nd' capability"); - NDlength = strlen(ND); - if (BS == 0) - errx(5, "Terminal must have 'le' or `bs' or `bc' capability"); - BSlength = strlen(BS); - - if (tgetflag("os")) - errx(5, "Terminal must not overstrike"); - if (LINES <= 0 || COLUMNS <= 0) - errx(5, "Must know the screen size"); - tcgetattr(0, &orig); - new = orig; - new.c_lflag &= ~(ECHO | ICANON); - new.c_oflag &= ~(ONLCR | OXTABS); - signal(SIGINT, stop); - ospeed = cfgetospeed(&orig); - new.c_cc[VSUSP] = _POSIX_VDISABLE; - new.c_cc[VDSUSP] = _POSIX_VDISABLE; - raw(); - - if (orig.c_oflag & OXTABS) - TA = 0; - putpad(KS); - putpad(TI); - point(&cursor, 0, LINES - 1); -} |