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?"