[alt.sources] looking for rot

coleman@inmet.inmet.com (04/29/91)

I am looking for the C source code for a program called 'rot'.  This program
uses curses, and when executed would cause all of the text on the terminal
screen to fall character by character to form a mountain of letters on the 
bottom of your terminal screen.  I would appreciate it if anyone has this lying
around or even knows what the $#$T I'm talking about. 

Thanks,

Jack

--

C. Jack Coleman II
Intermetrics Inc.
733 Concord Ave.
Cambridge, MA 02138

Internet: coleman@inmet.inmet.com

peter@ficc.ferranti.com (Peter da Silva) (05/01/91)

As the author of "rot":

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile rot.c
# Wrapped by peter@ficc.ferranti.com on Thu Dec 27 11:45:43 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(214 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Simple makefile for rot program
X# for that bloody stupid System V Make
XSHELL=/bin/sh
X
XCFLAGS = -O #-DSYSV
X
Xrot:	rot.c
X	cc $(CFLAGS) -o rot rot.c -ltermlib
X
Xrot.shar: Makefile rot.c
X	shar >rot.shar Makefile rot.c
END_OF_FILE
if test 214 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'rot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rot.c'\"
else
echo shar: Extracting \"'rot.c'\" \(10602 characters\)
sed "s/^X//" >'rot.c' <<'END_OF_FILE'
X/*
X * Revision History:
X *
X * Original source from:
X *  Peter da Silva (ihnp4!shell!neuro1!{hyd-ptd,datafact,baylor}!peter)
X *
X * Changes for padding added by:
X *  Andrew Scott Beals ({ucbvax,decwrl}!amdcad!bandy or bandy@amdcad.amd.com)
X *  20 April 1987
X *
X * Additional changes for padding, fix for computation of tglen,
X * increase max lines, improve termlib handling, add System V #ifdefs.
X *  Bill Randle (billr@tekred.TEK.COM)
X *  21 April 1987
X *
X * Some long-standing 8-bit bugs fixed, and more randomness added.
X *  Peter da Silva <peter@sugar.hackercorp.com> Dec 1 1989.
X *
X * ((char *)0) de-referencing removed. [Caused SEGV core dumps on Sun-3's]
X *  Andrew Scott Beals <bandy@toad.com> 7 May 1990
X *
X * "PG" emulation added Dec '90 by Peter da Silva, in a fit of boredom.
X * Now "rot" acts like a pager, only dumping the screen if you wait too long.
X */
X
X#include <stdio.h>
X
X#ifdef SYSV
X# include <termio.h>
X#else
X# include <sgtty.h>
X#endif
X
X#include <signal.h>
X
X/*		-- Miscellaneous defines --				     */
X#define FALSE 0
X#define TRUE 1
X#define MAXCOL 80
X#define MAXLI 34
X#define SLEEPFACTOR 2	/* Assumed reading speed, lines per second */
X#define COLRATIO 8	/* For delays, amount to discount columns by */
X
Xextern char *tgetstr();
X
Xint lastx, lasty;
Xstruct _c {
X	struct _c *c_next;
X	int c_line, c_column;
X	char c_mark;
X} *clist;
X
X/*		-- Global variables --					     */
Xchar *tent;                                               /* Pointer to tbuf */
Xextern char PC;                                             /* Pad character */
Xextern char *UP, *BC;                         /* Upline, backsapce character */
Xextern short ospeed;                                /* Terminal output speed */
Xint tglen;
X
Xchar *cm,                                                   /* Cursor motion */
X     *cl,                                                    /* Clear screen */
X     *ti,						    /* Init terminal */
X     *te;						   /* Reset terminal */
Xint  li,                                                  /* lines on screen */
X     co;                                                    /* columns ditto */
Xchar screen[MAXLI+1][MAXCOL];
Xchar newscreen[MAXLI+1][MAXCOL];
Xchar *me;						     /* program name */
X
X/* Options */
Xint packflag = 0;
X
Xmain(ac, av)
Xint ac;
Xchar **av;
X{
X	/* set ospeed so padding works correctly */
X#ifdef SYSV
X	struct termio	p;
X
X	if(ioctl(1, TCGETA, &p) != -1)
X		ospeed=p.c_cflag & CBAUD;
X#else
X	struct sgttyb	p;
X
X	if(ioctl(1, TIOCGETP, &p) != -1)
X		ospeed=p.sg_ospeed;
X#endif
X
X	me = *av;
X
X	srand(getpid());
X	tinit(getenv("TERM"));
X	while(ac > 1 && av[1][0]=='-') {
X		while(av[1][1]) {
X			switch(av[1][1]) {
X				case 'p': packflag=1; break;
X				default: fprintf(stderr, "%s [-p] [file]...\n", me);
X			}
X			av[1]++;
X		}
X		av++;
X		ac--;
X	}
X	if(ac > 1)
X		while(*++av)
X			dropf(*av);
X	else
X		fdropf(stdin);
X	tend();
X}
X
Xat(x, y, c)
Xint x, y;
Xchar c;
X{
X#ifdef DEBUG
X	_at(x, y);
X#else
X	if(y==lasty) {
X		if(x!=lastx) {
X			if(x<lastx && lastx-x<tglen)
X				while(x<lastx) {
X					putchar('\b');
X					lastx--;
X				}
X			else if(x>lastx && x-lastx<tglen)
X				while(x>lastx) {
X					putchar(0x7F&newscreen[lasty][lastx]);
X					lastx++;
X				}
X			else
X				_at(x, y);
X		}
X	} else
X		_at(x, y);
X#endif
X	c &= 0x7F;
X	putchar(c);
X	if(c >= ' ' && c != '\177')
X		lastx++;
X	if(lastx>=co) {
X		lastx -= co;
X		lasty++;
X	}
X}
X
X_at(x, y)
Xint x, y;
X{
X	extern void	outc();
X
X	tputs(tgoto(cm, x, y), 1, outc);	 /* handle padding */
X	lastx = x;
X	lasty = y;
X}
X
Xvoid
Xoutc(c)
Xregister c;
X{
X	putc(c&0x7F, stdout);
X}
X
Xtinit(name)
Xchar *name;
X{
X	static char junkbuf[1024], *junkptr;
X	char tbuf[1024];
X	int  intr();
X
X	junkptr = junkbuf;
X
X	tgetent(tbuf, name);
X
X	if (!tgetflag("bs"))		/* is backspace not used? */
X		BC = tgetstr("bc",&junkptr);	/* find out what is */
X	else
X		BC = "\b";		/* make a backspace handy */
X	if (tgetstr("pc", &junkptr) != NULL)
X		PC = *junkptr;  /* set pad character */
X	else
X		PC = '\0';
X	UP = tgetstr("up", &junkptr);
X	cm = tgetstr("cm", &junkptr);
X	if (cm == NULL) {
X		printf("Can't rot on dumb terminals.\n");
X		exit(1);
X	}
X	cl = tgetstr("cl", &junkptr);
X	ti = tgetstr("ti", &junkptr);
X	te = tgetstr("te", &junkptr);
X	li = min(tgetnum("li"), MAXLI);
X	if (li == -1)
X		li = 24;
X	co = min(tgetnum("co"), MAXCOL);
X	if (co == -1)
X		co = 80;
X	tglen = strlen(tgoto(cm, co-1, li-1));
X}
X
Xtend()
X{
X	if(te != NULL) outs(te);
X	_at(0, li-1);
X	putchar('\n');
X	fflush(stdout);
X}
X
Xreadscreen(fp)
XFILE *fp;
X{
X	int line, column, p;
X	char tmp[256];
X
X	for(line=0; line<li; line++)
X		for(column=0; column<co; column++)
X			{
X			newscreen[line][column] = screen[line][column] = ' ';
X			}
X	strncpy(&newscreen[li-1][0], "--Hit CR--", 10);
X	for(column=0; column<co; column++)
X		newscreen[li][column] = screen[li][column] = '*';
X	line=0;
X	while(line<li-1) {
X		if(!fgets(tmp, 256, fp))
X			return(max(line,column/COLRATIO));
X
X		for(column=0, p=0; tmp[p]; p++) {
X			tmp[p] &= ~0200;
X			if(tmp[p] < ' ' || tmp[p] == 127)
X				switch(tmp[p]) {
X					case '\t':
X						while(++column % 8)
X							continue;
X						break;
X					case '\n':
X						column = 0;
X						line++;
X						break;
X					default:
X						newscreen[line][column] = '^';
X						column++;
X						if(column>=co) {
X							column -= co;
X							line++;
X						}
X						newscreen[line][column] =
X							(tmp[p]+'@') & 127;
X						column++;
X						break;
X				}
X			else {
X				newscreen[line][column] = tmp[p];
X				column++;
X			}
X			if(column >= co) {
X				column -= co;
X				line++;
X			}
X			if(line >= li)
X				break;
X		}
X	}
X	for(column=0; column<co; column++)
X		newscreen[li][column] = screen[li][column] = '*';
X	return(max(line,column/COLRATIO));
X}
X
Xdrawscreen()
X{
X	lastx = lasty = 0;
X	outs(cl);
X	update();
X}
X
Xupdate() /* copy new screen back to old screen */
X{
X	int l, c;
X
X	for(l=0; l<li; l++)
X		for(c=0; c<co; c++)
X			if(screen[l][c] != newscreen[l][c]) {
X				if((screen[l][c] & ~0200) !=
X				   (newscreen[l][c] & ~0200))
X					at(c, l, newscreen[l][c]);
X				screen[l][c] = newscreen[l][c];
X			}
X}
X
Xdrop(line, column)
Xint line, column;
X{
X	struct _c *hold, *temp;
X
X	if(line<0 || line>=li || column<0 || column>=co ||
X	   (line>=li-2 && column >= co-1) || /* scroll potential */
X	   screen[line][column]==' ' || /* empty */
X	   screen[line][column] & 0200) /* already in list */
X		return;
X	if(screen[line+1][column]!=' ' &&
X	   (column==co-1 ||screen[line+1][column+1]!=' ') &&
X	   (column==0 ||screen[line+1][column-1]!=' '))
X		return;
X
X	hold = (struct _c *) malloc(sizeof(struct _c));
X	hold -> c_next;
X	hold -> c_column = column;
X	hold -> c_line = line;
X	hold -> c_mark = 0;
X	screen[line][column] |= 0200;
X
X	for(temp = clist; temp && temp->c_next; temp=temp->c_next)
X		if(!(rand()&1111))
X			break;
X	if(temp) {
X		hold->c_next = temp->c_next;
X		temp->c_next = hold;
X	} else {
X		hold->c_next = clist;
X		clist = hold;
X	}
X}
X
Xdrops()
X{
X	int l, c;
X	struct _c *hold;
X	for(hold = clist; hold; hold=hold->c_next) {
X		int line = hold->c_line, column=hold->c_column;
X		if(line>= li-2 && column>=co-1) {
X			newscreen[line][column] &= ~0200;
X			screen[line][column] &= ~0200;
X			hold->c_mark = 1;
X			continue;
X		}
X		if(newscreen[line+1][column+1] == ' ' &&
X		   newscreen[line+1][column-1] == ' ')
X			drop(line+1, column);
X		drop(line, column+1);
X		drop(line-1, column);
X		drop(line, column-1);
X		if(newscreen[line+1][column]==' ' ||
X		   (packflag &&
X		    newscreen[line+1][column]==(screen[line][column]&~0200)
X		   )
X		  ) {
X			newscreen[line+1][column] = screen[line][column];
X			newscreen[line][column] = ' ';
X			line++;
X		} else if(rand()&01000) {
X			if(column>0 && newscreen[line][column-1] == ' ' &&
X			    newscreen[line+1][column-1]==' ') {
X				newscreen[line][column-1] =
X					screen[line][column];
X				newscreen[line][column] = ' ';
X				column--;
X			}
X			else if(column<co-1 &&
X				newscreen[line][column+1] == ' ' &&
X				newscreen[line+1][column+1]==' ') {
X					newscreen[line][column+1] =
X						screen[line][column];
X					newscreen[line][column] = ' ';
X					column++;
X			}
X			else {
X				screen[line][column] &= ~0200;
X				newscreen[line][column] &= ~0200;
X				hold -> c_mark = 1;
X			}
X		} else {
X			if(column<co-1 && newscreen[line][column+1] == ' ' &&
X			    newscreen[line+1][column+1]==' ') {
X				newscreen[line][column+1] =
X					screen[line][column];
X				newscreen[line][column] = ' ';
X				column++;
X			}
X			else if(column>0 && newscreen[line][column-1] == ' ' &&
X			    newscreen[line+1][column-1]==' ') {
X				newscreen[line][column-1] =
X					screen[line][column];
X				newscreen[line][column] = ' ';
X				column--;
X			}
X			else {
X				newscreen[line][column] &= ~0200;
X				screen[line][column] &= ~0200;
X				hold -> c_mark = 1;
X			}
X		}
X		hold -> c_column = column;
X		hold -> c_line = line;
X		fflush(stdout);
X	}
X
X	while(clist && clist->c_mark) {
X		struct _c *p = clist;
X		clist = clist -> c_next;
X		free(p);
X	}
X	hold = clist;
X	while(hold && hold->c_next)
X		if(hold->c_next->c_mark) {
X			struct _c *p = hold->c_next;
X			hold->c_next = p->c_next;
X			free(p);
X		} else
X			hold=hold->c_next;
X}
X
Xdroplet(line, column)
Xint line, column;
X{
X	int ret;
X	if(line==li-1)
X		return 0;
X	while(column>=0 &&
X	      screen[line][column]!=' ' &&
X	      screen[line+1][column]==' ')
X		column--;
X	column++;
X	while(column<co &&
X	      screen[line][column]!=' ' &&
X	      screen[line+1][column]==' ')
X		drop(line, column++);
X	ret = clist != 0;
X	while(clist) {
X		drops();
X		update();
X	}
X	return ret;
X}
X
Xdropscreen()
X{
X	int column, line;
X	int rubbish = 0, count = 0;
X
X	do {
X		int start, limit, incr;
X		count++;
X		rubbish = 0;
X		if(count&1) { start=li-2; limit=0; incr = -1; }
X		else { start=0; limit=li-2; incr=1; }
X		for(line=start; line!=limit && !rubbish; line+=incr) {
X			if(line&1)
X				for(column=0; column<co && !rubbish; column++)
X					rubbish += droplet(line, column);
X			else
X				for(column=co-1; column>=0 && !rubbish; column--)
X					rubbish += droplet(line, column);
X		}
X	} while(rubbish);
X}
X
Xdropf(file)
Xchar *file;
X{
X	FILE *fp;
X
X	if(!(fp = fopen(file, "r"))) {
X		perror(file);
X		return -1;
X	}
X	fdropf(fp);
X}
X
Xfdropf(fp)
XFILE *fp;
X{
X	int i,lines;
X
X	while(!feof(fp)) {
X		lines=readscreen(fp);
X		drawscreen();
X		fflush(stdout);
X		if(more(lines) == 0) { /* Timed out */
X			for(i=0; i<20; i++)
X				droplet((rand()>>4) % (li-1), (rand()>>4) % co);
X			dropscreen();
X		}
X	}
X}
X
Xchar timed_out;
X
Xint tmo()
X{
X	timed_out = 1;
X}
X
Xmore(lines)
Xint lines;
X{
X	char c;
X
X	timed_out = 0;
X	signal(SIGALRM, tmo);
X	alarm(max(lines/SLEEPFACTOR,1));
X	while(!timed_out) {
X		read(0, &c, 1);
X		if(c=='\n' || c=='\r') break;
X	}
X	alarm(0);
X	return !timed_out;
X}
X
Xouts(s)
Xchar *s;
X{
X	fputs(s, stdout);
X}
X
Xmin(a, b)
Xint a, b;
X{
X	if(a<b) return a;
X	return b;
X}
X
Xmax(a, b)
Xint a, b;
X{
X	if(a>b) return a;
X	return b;
X}
END_OF_FILE
if test 10602 -ne `wc -c <'rot.c'`; then
    echo shar: \"'rot.c'\" unpacked with wrong size!
fi
# end of 'rot.c'
fi
echo shar: End of shell archive.
exit 0
-- 
Peter da Silva.  `-_-'  peter@ferranti.com
+1 713 274 5180.  'U`  "Have you hugged your wolf today?"