New upstream source

git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5102 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
joey
1999-09-26 21:26:52 +00:00
parent 5d36ad0e9e
commit fb38e489ce
10 changed files with 37 additions and 45483 deletions

View File

@@ -1,717 +0,0 @@
/* $NetBSD: move.c,v 1.15 1997/10/14 01:02:48 lukem 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.15 1997/10/14 01:02:48 lukem 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 <unistd.h> /* For _POSIX_VDISABLE */
#include "snake.h"
int CMlength;
int NDlength;
int BSlength;
int delaystr[10];
#ifndef NCURSES_VERSION
speed_t ospeed;
#endif
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)
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)
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(struct point * ps, const char *fmt,...)
#else
apr(ps, fmt, va_alist)
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)
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);
}
}
int
outch(c)
int c;
{
return putchar(c);
}
void
putpad(str)
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
my_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;
#ifdef VDSUSP
new.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif
my_raw();
if (orig.c_oflag & OXTABS)
TA = 0;
putpad(KS);
putpad(TI);
point(&cursor, 0, LINES - 1);
}

View File

@@ -1,130 +0,0 @@
/* $NetBSD: snake.h,v 1.10 1998/09/13 15:27:30 hubertf 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.
*
* @(#)snake.h 8.1 (Berkeley) 5/31/93
*/
# include <sys/types.h>
# include <sys/ioctl.h>
# include <assert.h>
# include <err.h>
# include <math.h>
# include <signal.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <termcap.h>
# include <termios.h>
#define ESC '\033'
struct tbuffer {
long t[4];
} tbuffer;
char *CL, *UP, *DO, *ND, *BS,
*HO, *CM,
*TA, *LL,
*KL, *KR, *KU, *KD,
*TI, *TE, *KS, *KE;
int LINES, COLUMNS; /* physical screen size. */
int lcnt, ccnt; /* user's idea of screen size */
char PC;
int AM, BW;
char tbuf[1024], tcapbuf[128];
int Klength; /* length of KX strings */
int chunk; /* amount of money given at a time */
#ifndef NCURSES_VERSION
speed_t ospeed;
#endif
#ifdef debug
#define cashvalue (loot-penalty)/25
#else
#define cashvalue chunk*(loot-penalty)/25
#endif
struct point {
int col, line;
};
struct point cursor;
struct termios orig, new;
#define same(s1, s2) ((s1)->line == (s2)->line && (s1)->col == (s2)->col)
void apr __P((struct point *, const char *, ...));
void bs __P((void));
void chase __P((struct point *, struct point *));
int chk __P((struct point *));
void clear __P((void));
void cook __P((void));
void cr __P((void));
void delay __P((int));
void done __P((void)) __attribute__((__noreturn__));
void down __P((void));
void drawbox __P((void));
void flushi __P((void));
void getcap __P((void));
void gto __P((struct point *));
void home __P((void));
void length __P((int));
void ll __P((void));
void logit __P((const char *));
void mainloop __P((void));
void move __P((struct point *));
void nd __P((void));
int outch __P((int));
void pch __P((int));
void pchar __P((struct point *, char));
struct point *point __P((struct point *, int, int));
int post __P((int, int));
void pr __P((const char *, ...));
void pstring __P((const char *));
int pushsnake __P((void));
void putpad __P((char *));
void my_raw __P((void));
void right __P((struct point *));
void setup __P((void));
void snap __P((void));
void snap __P((void));
void snrand __P((struct point *));
void spacewarp __P((int));
void stop __P((int)) __attribute__((__noreturn__));
int stretch __P((struct point *));
int stretch __P((struct point *));
void surround __P((struct point *));
void suspend __P((void));
void up __P((void));
void win __P((struct point *));
void winnings __P((int));