Subject: v06i017: tetris - popular game of dropping blocks, Part02/02
From: [email-masked]
Newsgroups: comp.sources.games

Submitted-by: Martin Heidegger <[email-masked]>
Posting-number: Volume 6, Issue 17
Archive-name: tetris/Part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 2)."
# Contents:  FILES Makefile check_block.c check_horiz.c csr.h cursive.c
#   display_high.c draw_shadow.c drop_block.c erase_horiz.c
#   get_level.c help.tetris redefine.c save_game.c score.c
#   score.tetris set_level.c setup_next.c tetris.h tetris.man useful.c
# Wrapped by billr@saab on Tue Feb 28 12:49:59 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'FILES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'FILES'\"
else
echo shar: Extracting \"'FILES'\" \(1751 characters\)
sed "s/^X//" >'FILES' <<'END_OF_FILE'
X	You should have:
X
XMakefile:	this is the makefile, it needs some modification of directory
X		names
X
Xtetris.man:	this is the unix style manual page formatted in -man macros
X		you can modify the filenames in it to reflect where you 
X		end up placing some of tetris' utility files.
X
Xhelp.tetris:	this is the online help file, it will be moved by the makefile
Xscore.tetris:	this is the file that keeps score, it is not necessary that
X		it really exist, as tetris will make it if it doesn't exist
X
Xmonitor.tetris: this is the super snoopy big brother file, it tells the owner
X		of tetris who played, when they played and how they did.
X		this filename can be declared as "/dev/null" in the file
X		tetris.h and this will effectively turn the monitoring process
X		off. This file is like score.tetris, it doesn't have to exist
X		for tetris, as tetris will make it itself. I think that the
X		makefile will complain if these two files aren't around,
X		but no big deal, just touch the filenames.
X
Xcsr.h		this is the include file for the cursor package I use
X		I don't use curses because it is too slow. This may
X		cause portability problems, but then I didn't concern
X		myself with that when I wrote tetris.
X
Xtetris.h	this is the include file for tetris itself. You will need
X		to modify pathnames that are defined in this file or tetris
X		will not like you. I will trap for these nasties in the
X		future but right now I am too lazy.
X
XThe rest of the files are the source files, this is a manifest of them:
X
Xcheck_block.c
Xcheck_horiz.c
Xcsr.c
Xcursive.c
Xdefine_shapes.c
Xdisplay_high.c
Xdraw_shadow.c
Xdrop_block.c
Xend_game.c
Xerase_horiz.c
Xget_level.c
Xinit_tetris.c
Xmain.c
Xprint_shape.c
Xprocess_input.c
Xredefine.c
Xsave_game.c
Xscore.c
Xset_level.c
Xsetup_next.c
Xuseful.c
END_OF_FILE
if test 1751 -ne `wc -c <'FILES'`; then
    echo shar: \"'FILES'\" unpacked with wrong size!
fi
# end of 'FILES'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1722 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Makefile for tetris 
X#
X# 2/23/89
X#
X# adam margulies [email-masked]
X#                {...}!ucbvax!ucscc!ssyx!vespa
X#
X# makes: tetris debug install clean docs shar all new
X#
X# if this is a new installation use 'make new'
X#
X
X# where the binary will go
XDESTDIR = /usr/games
X
X# where the lib files go
XLIBDIR = /usr/games/lib/tetris
X
X# where the documentation goes
XDOCDIR = /usr/games/Doc
X
X# what the documentation is called
XDOCNAME = tetris.doc
X
XINC = 	tetris.h csr.h
X
XOBJ = 	check_block.o\
X	check_horiz.o\
X	csr.o\
X	cursive.o\
X	define_shapes.o\
X	display_high.o\
X	draw_shadow.o\
X	drop_block.o\
X	end_game.o\
X	erase_horiz.o\
X	get_level.o\
X	init_tetris.o\
X	main.o\
X	print_shape.o\
X	process_input.o\
X	redefine.o\
X	save_game.o\
X	score.o\
X	set_level.o\
X	setup_next.o\
X	useful.o
X
Xtetris: $(OBJ) $(INC)
X	cc -O -s -o tetris $(OBJ) -ltermcap
X	chmod 2711 tetris
X	@echo "binary ready"
X
Xdebug: $(OBJ) $(INC)
X	cc -g -o tetris $(OBJ) -ltermcap
X	chmod 2711 tetris
X	@echo "debug binary ready"
X
Xinstall:
X	install tetris $(DESTDIR)
X	chmod 2711 $(DESTDIR)/tetris
X
X	@echo "done"
X
Xclean:
X	/bin/rm -rf *.o tetris core nroff.out make.out
X
Xdocs:
X	@/bin/rm -rf nroff.out
X	nroff -man tetris.man > nroff.out
X
X	@/bin/rm -rf $(DOCDIR)/$(DOCNAME)
X	mv nroff.out $(DOCDIR)/$(DOCNAME)
X	chmod 664 $(DOCDIR)/$(DOCNAME)
X
X	@echo "docs ready"
X
Xshar:
X	@/bin/rm -rf ../tetris.shar
X	shar README FILES Makefile help.tetris score.tetris monitor.tetris\
X	*.c *.h tetris.man > ../tetris.shar
X
X	@echo "shar ready"
X
Xall: clean docs tetris
X
Xnew:	all
X	@/bin/rm -rf $(LIBDIR)/{help, monitor, score}.tetris
X	@touch monitor.tetris
X	@touch score.tetris
X	mv {help, monitor, score}.tetris $(LIBDIR)
X	chmod 664 $(LIBDIR)/{help, monitor, score}.tetris
X
Xinit_tetris.o: tetris.h
END_OF_FILE
if test 1722 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'check_block.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'check_block.c'\"
else
echo shar: Extracting \"'check_block.c'\" \(3597 characters\)
sed "s/^X//" >'check_block.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: check_block()                                                   */
X/*                                                                         */
X/*    checks to make sure that the moving shape can proceed to the next    */
X/*    line on the screen. the function returns 0 if the shape can't move   */
X/*    on to the line below, 1 otherwise.                                   */
X
X#include "tetris.h"
X
Xint check_block()
X{
X	int x = curx, y = cury, sh = current->shape, rt = current->rot;
X    if (y > (21 - current->height))         /* reached bottom of screen */
X        return(0);
X
X    /* These lines check to make sure that the next line is clear */
X
X        if (shape[sh].table[3][rt] & 8 &&
X            window0[y+4][x] != ' ')
X                return(0);
X        if (shape[sh].table[3][rt] & 4 &&
X            window0[y+4][x+1] != ' ')
X                return(0);
X        if (shape[sh].table[3][rt] & 2 &&
X            window0[y+4][x+2] != ' ')
X                return(0);
X        if (shape[sh].table[3][rt] & 1 &&
X            window0[y+4][x+3] != ' ')
X                return(0);
X
X    /* These lines check to make sure that line 2 of the shape doesn't snag */
X
X        if ((shape[sh].table[2][rt] & 8) &&
X            (window0[y+3][x] != ' ' &&
X            !(shape[sh].table[3][rt] & 8)))
X                return(0);
X        if (shape[sh].table[2][rt] & 4 &&
X            (window0[y+3][x+1] != ' ' &&
X            !(shape[sh].table[3][rt] & 4)))
X                return(0);
X        if (shape[sh].table[2][rt] & 2 &&
X            (window0[y+3][x+2] != ' ' &&
X            !(shape[sh].table[3][rt] & 2)))
X                return(0);
X        if (shape[sh].table[2][rt] & 1 &&
X            (window0[y+3][x+3] != ' ' &&
X            !(shape[sh].table[3][rt] & 1)))
X                return(0);
X
X    /* These lines check to make sure that line 1 of the shape doesn't snag */
X
X    if (y > -1) {
X        if (shape[sh].table[1][rt] & 8 &&
X            window0[y+2][x] != ' ' &&
X            !(shape[sh].table[2][rt] & 8))
X                return(0);
X        if (shape[sh].table[1][rt] & 4 &&
X            (window0[y+2][x+1] != ' ' &&
X            !(shape[sh].table[2][rt] & 4)))
X                return(0);
X        if (shape[sh].table[1][rt] & 2 &&
X            (window0[y+2][x+2] != ' ' &&
X            !(shape[sh].table[2][rt] & 2)))
X                return(0);
X        if (shape[sh].table[1][rt] & 1 &&
X            (window0[y+2][x+3] != ' ' &&
X            !(shape[sh].table[2][rt] & 1)))
X                return(0);
X    }
X
X    /* These lines check to make sure that line 0 of the shape doesn't snag */
X
X    if (y > 0) {
X        if (shape[sh].table[0][rt] & 8 &&
X            (window0[y+1][x] != ' ' &&
X            !(shape[sh].table[1][rt] & 8)))
X                return(0);
X        if (shape[sh].table[0][rt] & 4 &&
X            (window0[y+1][x+1] != ' ' &&
X            !(shape[sh].table[1][rt] & 4)))
X                return(0);
X        if (shape[sh].table[0][rt] & 2 &&
X            (window0[y+1][x+2] != ' ' &&
X            !(shape[sh].table[1][rt] & 2)))
X                return(0);
X        if (shape[sh].table[0][rt] & 1 &&
X            (window0[y+1][x+3] != ' ' &&
X            !(shape[sh].table[1][rt] & 1)))
X                return(0);
X    }
X
X    /* successful drop, return */
X    return(1);
X}
END_OF_FILE
if test 3597 -ne `wc -c <'check_block.c'`; then
    echo shar: \"'check_block.c'\" unpacked with wrong size!
fi
# end of 'check_block.c'
fi
if test -f 'check_horiz.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'check_horiz.c'\"
else
echo shar: Extracting \"'check_horiz.c'\" \(1212 characters\)
sed "s/^X//" >'check_horiz.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: check_horiz()                                                    */
X/*                                                                          */
X/*   this function is called after the shape has stopped and before a       */
X/*   new shape begins dropping. it checks to see if a horizontal line       */
X/*   is complete and if so calls erase_horiz() to erase it.                 */
X/*                                                                          */
X#include "tetris.h"
X
Xvoid check_horiz()
X{
X    int i,j,flag;                /* i and j are counters, flag is 0 if a row
X                                   is complete                                */
X
X    for (i = 2; i < 22; i++) {
X        flag = 0;
X        for (j=35; j<45; j++) {
X            if (window0[i][j] == ' ')
X                flag=1;
X        }    
X        if (!flag)
X            erase_horiz(i);
X    }
X}
END_OF_FILE
if test 1212 -ne `wc -c <'check_horiz.c'`; then
    echo shar: \"'check_horiz.c'\" unpacked with wrong size!
fi
# end of 'check_horiz.c'
fi
if test -f 'csr.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'csr.h'\"
else
echo shar: Extracting \"'csr.h'\" \(810 characters\)
sed "s/^X//" >'csr.h' <<'END_OF_FILE'
X#include <sgtty.h>
X
X#ifdef EXPANSION
X#define MAX_X 132
X#define MAX_Y 48
X#else
X#define MAX_X 80
X#define MAX_Y 24
X#endif
X
Xchar	window0[MAX_Y][MAX_X];
Xchar	window1[MAX_Y][MAX_X];
Xchar	window2[MAX_Y][MAX_X];
X
Xchar    *tc_ce;
Xchar    *tc_cm;
Xchar    *tc_cl;
Xchar    *tc_up;
Xchar    *tc_do;
Xint     putch();
Xint	_csrx, _csry, _rx, _ry;
X
X#define move(y,x)		(_csry =y, _csrx =x)
X#define mvaddch(y,x,ch)		((window1[y][x] = ch))
X#define addch(ch)		window1[_csry][_csrx++] = ch
X#define erase(y,x,n)		tospaces(&window1[y][x], n)
X
X#define cls() 			(tputs(tc_cl, 0, putch))
X#define csr(row,col)		(tputs(tgoto(tc_cm, col, row), 0, putch),\
X								_csry = row, _csrx = col)
X
X#define stty(a,b)		ioctl(a, TIOCSETN, b)
X
Xstruct sgttyb tty, orig_tty;
Xstruct ltchars ltc, orig_ltc;
Xstruct tchars tc, orig_tc;
Xextern short ospeed;
X
END_OF_FILE
if test 810 -ne `wc -c <'csr.h'`; then
    echo shar: \"'csr.h'\" unpacked with wrong size!
fi
# end of 'csr.h'
fi
if test -f 'cursive.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cursive.c'\"
else
echo shar: Extracting \"'cursive.c'\" \(1635 characters\)
sed "s/^X//" >'cursive.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: cursive()                                                         */
X/* Draws the word "Tetris" in cursive writing on the screen                     */
X#include "tetris.h"
X
Xvoid 
Xcursive()
X{
X    mvaddstr(0, 0, "_____                      ");
X    mvaddstr(1, 0, "  |  _ ___  _  .  _        ");
X    mvaddstr(2, 0, "  | (_  |  | ) | (         ");
X    mvaddstr(3, 0, "  | (_  |  | \\ | _)        ");
X    mvaddstr(4, 0, "              the addiction");
X
X    /* Capital T */
X    csr_draw(0, 0, 0, 4);
X    csr_draw(1, 2, 1, 2);
X    csr_draw(2, 2, 2, 2);
X    csr_draw(3, 2, 3, 2);
X
X    /* Little e */
X    csr_draw(1, 5, 1, 5);
X    csr_draw(2, 4, 2, 4);
X    csr_draw(2, 5, 2, 5);
X    csr_draw(3, 4, 3, 4);
X    csr_draw(3, 5, 3, 5);
X
X    /* Little t */
X    csr_draw(1, 7, 1, 7);
X    csr_draw(1, 8, 1, 8);
X    csr_draw(1, 9, 1, 9);
X    csr_draw(2, 8, 2, 8);
X    csr_draw(3, 8, 3, 8);
X
X    /* Little r */
X    csr_draw(3, 11, 3, 11);
X    csr_draw(2, 11, 2, 11);
X    csr_draw(1, 12, 1, 12);
X    csr_draw(2, 13, 2, 13);
X    csr_draw(3, 11, 3, 15);
X
X    /* Little i */
X    csr_draw(2, 15, 2, 15);
X    csr_draw(3, 15, 3, 16);
X
X    /* Little s */
X    csr_draw(1, 18, 1, 18);
X    csr_draw(2, 17, 2, 17);
X    csr_draw(3, 18, 3, 18);
X    csr_draw(3, 17, 3, 17);
X
X    csr_draw(1, 15, 1, 15);
X
X    csr_draw(4, 0, 4, 26);
X}
END_OF_FILE
if test 1635 -ne `wc -c <'cursive.c'`; then
    echo shar: \"'cursive.c'\" unpacked with wrong size!
fi
# end of 'cursive.c'
fi
if test -f 'display_high.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'display_high.c'\"
else
echo shar: Extracting \"'display_high.c'\" \(1556 characters\)
sed "s/^X//" >'display_high.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/*
X** display_high.c
X**
X** Displays the high score list
X**
X*/
X#include "tetris.h"
X
Xdisplay_high() 
X{
X	FILE *fp, *fopen();
X	int counter, i;
X
X    cls();
X	mvaddstr(0,15," _____   ____  _____   ____   __   ____");      
X	mvaddstr(1,15,"/\\    \\ /\\   \\/\\    \\ /\\   \\ /\\ \\ /\\   \\");  
X	mvaddstr(2,15,"\\/_  _// / __/\\/_  _// /   // / // / __/");      
X	mvaddstr(3,15,"/ / / / / __/ / / / / /  _// / //\\/_  /");      
X	mvaddstr(4,15,"\\/_/  \\/___/  \\/_/  \\/___\\ \\/_/ \\/___/");       
X												  
X	csr_draw(0,14,4,60);
X	resetty();
X
X	printf("\n");
X	printf("\n");
X
X	if ((fp = fopen(HIGHSCOREFILE, "r")) == NULL){
X		SIGHOLD(14);
X		cls();
X		csr(23,0);
X		resetty();
X		fprintf(stderr, "%s\n", HIGHSCOREFILE);
X		perror("opening highscore file");
X		exit(3);
X	}
X
X	flock(fileno(fp), LOCK_EX);
X	for(counter=0;counter<15;counter++){
X		fscanf(fp, "%d\n", &high_score[counter]);
X		fscanf(fp, "%s\n", high_user[counter]);
X		fgets(high_name[counter], 255, fp);
X		for (i=0; i<255; i++)
X			if (high_name[counter][i] == '\n')
X				high_name[counter][i] = '\0';	
X		printf("     %2.2d. %7.7d %40.40s (%s)    \n", counter+1,
X			high_score[counter], high_name[counter], high_user[counter]);
X	}
X		flock(fileno(fp), LOCK_UN);
X		fclose(fp);
X} 
END_OF_FILE
if test 1556 -ne `wc -c <'display_high.c'`; then
    echo shar: \"'display_high.c'\" unpacked with wrong size!
fi
# end of 'display_high.c'
fi
if test -f 'draw_shadow.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'draw_shadow.c'\"
else
echo shar: Extracting \"'draw_shadow.c'\" \(655 characters\)
sed "s/^X//" >'draw_shadow.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: draw_shadow.c
X** 
X** draws the shadow of the block at row 21
X** 
X*/
X#include "tetris.h"
X
Xvoid draw_shadow() {
X
X	int i;
X
X	for(i=35; i<45; i++) {
X		if ( i >= (curx + (xoffset ? 1 : 0)) && 
X					i < (curx + current->width + (xoffset ? 1 : 0)) )
X			mvaddch(22,i,'=');
X		else mvaddch(22,i,'-');
X	}
X	csr_draw(22,35,22,44);
X}
END_OF_FILE
if test 655 -ne `wc -c <'draw_shadow.c'`; then
    echo shar: \"'draw_shadow.c'\" unpacked with wrong size!
fi
# end of 'draw_shadow.c'
fi
if test -f 'drop_block.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'drop_block.c'\"
else
echo shar: Extracting \"'drop_block.c'\" \(2848 characters\)
sed "s/^X//" >'drop_block.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: drop_block()                                                 */
X/*                                                                      */
X/* This function calls check_block() to make sure that the block        */
X/* can drop down the screen. If so it increments the current y          */
X/* position and calls print_shape() with a "color" of ' '. This         */
X/* erases the shape. If the player has not requested                    */
X/* a "fast drop" or the block has reached the bottom then the           */
X/* function draws the shape with a call to print_shape() and returns.   */
X/*                                                                      */
X/* If check_block() shows that the shape has been blocked then it gets  */
X/* trickier. If the current y position is too high then the game is     */
X/* over (i.e. the player has not successfully negotiated the block      */
X/* past the top of the screen). A call to score() updates the score     */
X/* and a call to end_game() terminates the program.                     */
X/*                                                                        */
X/* If the above is false then the program knows that the block has      */
X/* successfully come to rest. The call to score() is made to record     */
X/* the score and check_horiz() is called to clear any complete horiz    */
X/* lines then setup_next() is called to ready the next block.           */
X#include "tetris.h"
X#include <sys/ioctl.h>
X
Xvoid drop_block()
X{
X    void end_game(), check_horiz();
X	int num_char_pend;
X
X	ioctl(1, TIOCOUTQ, &num_char_pend); /* this checks the number of characters
X										   pending on the terminal */
X
X	if (num_char_pend != 0)
X		return;
X
X    if (check_block()) {
X        cury++;
X        print_shape(current->shape, curx, cury-1, current->rot, ' ');
X        if (!fast_drop || (cury + current->height == 22)) 
X            print_shape(current->shape, curx, cury, current->rot,
X                            current->color);
X    }
X    else {
X        if (cury < 2) {
X            if (fast_drop)
X                print_shape(current->shape, curx, cury, current->rot,
X                            current->color);
X            score(cury + current->height - 1);
X            end_game();
X        }
X        else {
X            if (fast_drop)
X                print_shape(current->shape, curx, cury, current->rot,
X                            current->color);
X            score(cury + current->height - 1);
X            check_horiz();
X            setup_next();
X        }
X    }
X
X}
END_OF_FILE
if test 2848 -ne `wc -c <'drop_block.c'`; then
    echo shar: \"'drop_block.c'\" unpacked with wrong size!
fi
# end of 'drop_block.c'
fi
if test -f 'erase_horiz.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'erase_horiz.c'\"
else
echo shar: Extracting \"'erase_horiz.c'\" \(1218 characters\)
sed "s/^X//" >'erase_horiz.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: erase_horiz.c                                                  */
X/*                                                                        */
X/* Upon being called by check_horiz() this function updates the           */
X/* window array to erase the completed horizontal row.                    */
X/* It also increments the level for every tenth row that is eaten.        */
X#include "tetris.h"
X
Xerase_horiz(row)
Xint row;
X{
X    int i,j;
X
X	if (row>2)
X		for(i=row-1; i>1; i--) 
X			for(j=35; j<45; j++)
X				window1[i+1][j] = window1[i][j];
X	for(j=35; j<45; j++)
X		window1[2][j] = ' ';
X				
X
X    csr_draw(2,35,row,44);
X
X    move(1,65);
X    printc("lines: %3.3d", ++lines);
X    if(lines && !(lines % 10) && ((lines/10) > level)) {
X        move(2,65);
X        printc("level: %2.2d", ++level);
X        next->color = '0' + (level % 10);
X        set_level();
X    }
X    csr_draw(1,65,2,79);
X}
END_OF_FILE
if test 1218 -ne `wc -c <'erase_horiz.c'`; then
    echo shar: \"'erase_horiz.c'\" unpacked with wrong size!
fi
# end of 'erase_horiz.c'
fi
if test -f 'get_level.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'get_level.c'\"
else
echo shar: Extracting \"'get_level.c'\" \(3558 characters\)
sed "s/^X//" >'get_level.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* get_level.c	
X**
X** Gets the level the user prefers to start on and also gets the users 
X** preference on "rubble" and generates the "rubble". Rubble is random
X** stuff put on the playing field to spice up the game at the beginning.
X*/
X#include "tetris.h"
X
Xvoid get_level()	
X{
X	int i;
X	save_screen(5,19,16,62);
X	clear(5,19,16,62);
X
X	mvaddstr(05,19, "+-----------------------------------------+");
X	mvaddstr(06,19, "| Starting level:                         |");
X	mvaddstr(15,19, "|    [hjkl] to move, [space] to toggle    |");
X	for(i=7; i<15; i++)
X		mvaddstr(i,19,"|                                         |");
X	mvaddstr(11,19, "| Rows of obstacles:                      |");
X	mvaddstr(16,19,"+-----------------------------------------+");
X
X	mvaddstr(07,21,"**** **** **** **** **** **** **** ****");
X	mvaddstr(08,21,"*00* *01* *03* *05* *07* *09* *11* *13*");
X	mvaddstr(09,21,"**** **** **** **** **** **** **** ****");
X
X	mvaddstr(12,21,"**** **** **** **** **** **** **** ****");
X	mvaddstr(13,21,"*00* *01* *03* *05* *07* *09* *11* *13*");
X	mvaddstr(14,21,"**** **** **** **** **** **** **** ****");
X
X	read_input();
X
X	restore_screen(5,19,16,62);
X
X}
X
Xread_input()
X{
X	int x = 0;
X	int y = 8;
X	char c;
X	
X	mvaddstr(7, 21, "++++");
X	mvaddch(8, 21, '+');
X	mvaddch(8, 24, '+');
X	mvaddstr(9, 21, "++++");
X
X	mvaddstr(12, 21,"++++");
X	mvaddch(13,21, '+');
X	mvaddch(13,24, '+');
X	mvaddstr(14, 21,"++++");
X	csr_draw(5,19,16,62);
X
X	csr(y, 23 + (x*5));
X
X	while(1){
X		c = getchar();
X		switch(c) {
X			case 'h':
X				x -= 1;
X				x = (x<0 ? 7 : x);
X				csr(y, 23 + (x*5));
X				break;
X			case 'l':
X				x += 1;
X				x = (x>7 ? 0 : x);
X				csr(y, 23 + (x*5));
X				break;
X			case 'j':
X				y = (y==8 ? 13 : 8);
X				csr(y, 23 + (x*5));
X				break;
X			case 'k':
X				y = (y==8 ? 13 : 8);
X				csr(y, 23 + (x*5));
X				break;
X			case ' ': 
X				mvaddstr((y == 8 ? 7 : 12), 21 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5),"****");
X				mvaddch((y == 8 ? 8 : 13),21 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5), '*');
X				mvaddch((y == 8 ? 8 : 13),24 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5), '*');
X				mvaddstr((y == 8 ? 9 : 14), 21 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5),"****");
X				csr_draw((y == 8 ? 7 : 12),21 + ((y == 8 ?
X					(level+1)/2 : (rubble+1)/2)*5),
X					(y == 8 ? 9 : 14), 24 + ((y == 8 ?
X					(level+1)/2 : (rubble+1)/2)*5));
X				if(y == 8)
X					level = (x == 0 ? 0 : (2*x) - 1);
X				else
X					rubble = (x == 0 ? 0 : (2*x) - 1);
X				mvaddstr((y == 8 ? 7 : 12), 21 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5),"++++");
X				mvaddch((y == 8 ? 8 : 13),21 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5), '+');
X				mvaddch((y == 8 ? 8 : 13),24 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5), '+');
X				mvaddstr((y == 8 ? 9 : 14), 21 +
X					((y == 8 ? (level+1)/2 : (rubble+1)/2)*5),"++++");
X				csr_draw((y == 8 ? 7 : 12),21 + ((y == 8 ?
X					(level+1)/2 : (rubble+1)/2)*5),
X					(y == 8 ? 9 : 14), 24 + ((y == 8 ?
X					(level+1)/2 : (rubble+1)/2)*5));
X				csr(y, 23 + (x*5));
X				break;	
X			default:
X				return;
X		}
X	}
X}
X
Xmake_rubble()
X{
X	int i,j;
X	char color[8];
X
X	strcpy(color, "#$%@&*+");
X
X	for(i=21; i>21-rubble; i--) 
X		for(j=35; j<45; j++) 
X			if((random() % 100) > 60)
X				mvaddch(i,j,color[(random() % 7)]);
X}
END_OF_FILE
if test 3558 -ne `wc -c <'get_level.c'`; then
    echo shar: \"'get_level.c'\" unpacked with wrong size!
fi
# end of 'get_level.c'
fi
if test -f 'help.tetris' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'help.tetris'\"
else
echo shar: Extracting \"'help.tetris'\" \(1834 characters\)
sed "s/^X//" >'help.tetris' <<'END_OF_FILE'
X
X                          TETRIS COMMANDS
Xh- move block left                         This game was supposedly written  
Xl- move block right                     by some soviet kid. You try to drop the
Xj- rotate block counter-clockwise       the blocks into complete horizontal
Xk- rotate block clockwise               rows; when you do, that row disappears.
X
Xn- turn on/off next block display       For every tenth row that disappears,
Xb- turn on/off shadowing                the level is increased.
Xspace- drop block quickly               The game ends when a shape cannot drop
X                                        past the top of the screen. 
XD- redefine keys
XP- pause, any key to resume              
XQ- quit
XS- save                                                                       
X                                           adam margulies, [email-masked]
X
X
X                      [PRESS ANY KEY FOR NEXT SCREEN]
X
X
X                          TETRIS SCORING
X
X    There are seven blocks in tetris, each rotation has its own point value.
X
X               $       @@      &&      *   ***    +     +++
X    #### 5   $$$ 5     @@ 6  &&  6   *** 6 *   6  +++ 6   + 6
X                     
X     #         $$$ 6     @     &      **   *       ++    +
X     # 8   $    $    $  @@ 7   && 7    * 7 *  6    +  7  + 7
X     #     $$ 5   5 $$  @       &      *   **      +    ++
X     #     $         $
X
X    In addition, a point is scored for each level above the bottom that the
Xblock comes to rest. If the space bar is pressed, a point is scored for
Xeach row above the bottom that block is at. The level bonus is two times the
Xthe current level per block. If the next block display or the block shadowing
Xis on then the level bonus is reduced by a number equal to the current level.
X                     [PRESS ANY KEY TO RETURN TO GAME]
X
END_OF_FILE
if test 1834 -ne `wc -c <'help.tetris'`; then
    echo shar: \"'help.tetris'\" unpacked with wrong size!
fi
# end of 'help.tetris'
fi
if test -f 'redefine.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'redefine.c'\"
else
echo shar: Extracting \"'redefine.c'\" \(1474 characters\)
sed "s/^X//" >'redefine.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* redefine.c
X**
X** allows redefinition of keys
X*/
X#include "tetris.h"
X
X
Xvoid redefine()
X{
X	char c;
X	int i;
X
X	save_screen(0,0,23,79);
X	clear(0,0,23,79);
X
X	mvaddstr(10,10,"Redefining keys. . .");
X	move(12,15);
X	printc("move left:          %c", key->left);
X	move(13,15);
X	printc("move right:         %c", key->right);
X	move(14,15);
X	printc("rotate ccw:         %c", key->rotleft);
X	move(15,15);
X	printc("rotate cw:          %c", key->rotright);
X	move(16,15);
X	printc("drop:               %c", key->drop);
X	move(17,15);
X	printc("toggle next block:  %c", key->togdisp);
X	move(18,15);
X	printc("toggle shadowing:   %c", key->togshad);
X	csr_draw(0,0,23,79);
X
X	for(i=12; i<19; i++) {
X		mvaddch(i,38,'?');
X		csr_draw(i,38,i,38);
X		c = getchar();
X		mvaddch(i,38,c);
X		csr_draw(i,38,i,38);
X		switch(i) {
X			case 12:
X				key->left = c;
X				break;
X			case 13:
X				key->right = c;
X				break;
X			case 14:
X				key->rotleft = c;
X				break;
X			case 15:
X				key->rotright = c;
X				break;
X			case 16:
X				key->drop = c;
X				break;
X			case 17:
X				key->togdisp = c;
X				break;
X			case 18:
X				key->togshad = c;
X		}
X	}
X	restore_screen(0,0,23,79);
X	csr_draw(0,0,23,79);
X}
END_OF_FILE
if test 1474 -ne `wc -c <'redefine.c'`; then
    echo shar: \"'redefine.c'\" unpacked with wrong size!
fi
# end of 'redefine.c'
fi
if test -f 'save_game.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'save_game.c'\"
else
echo shar: Extracting \"'save_game.c'\" \(1925 characters\)
sed "s/^X//" >'save_game.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: save_game.c
X**
X** Saves the game
X**
X*/
X#include "tetris.h"
X
Xvoid save_game() {
X
X	FILE *fp;
X	int i,j;	
X	struct stat buf;
X
X	if ((fp = fopen(rcd_file, "w")) == NULL){
X		SIGHOLD(14);
X		cls();
X		csr(23,0);
X		resetty();
X		fprintf(stderr, "%s\n", rcd_file);
X		perror("opening save file");
X		exit(3);
X	}
X
X	mvaddstr(23,0,"Got here [1]");
X	csr_draw(23,0,23,79);
X
X	stat(rcd_file, &buf);
X	for(i=0; i<20; i++) {
X		for(j=0; j<10; j++)
X			putc(window0[i+2][j+35], fp);
X		putc('\n', fp);
X	}
X
X	mvaddstr(23,0,"Got here [0]");
X	csr_draw(23,0,23,79);
X
X	fprintf(fp, "%ld\n", buf.st_ctime);
X	fprintf(fp, "%d\n", VERSION);
X	fprintf(fp, "%d\n%d\n%d\n", points, level, lines);
X	fprintf(fp, "%d\n", disp_next);
X	fprintf(fp, "%d\n", shadow);
X	fprintf(fp, "%d\n", disp_tomb);
X	fprintf(fp, "%d\n", disp_high);
X	fprintf(fp, "%d\n%d\n", cury, curx);
X	fprintf(fp, "%d\n%d\n", current->shape, current->rot);
X	fprintf(fp, "%d\n", current->was_shown);
X	fprintf(fp, "%d\n", current->was_shadowed);
X	fprintf(fp, "%d\n%d\n", next->shape, next->rot);
X	fprintf(fp, "%d\n", next->was_shown);
X	fprintf(fp, "%d\n", next->was_shadowed);
X	fprintf(fp, "%d\n", addict);
X	fprintf(fp, "%c\n", key->right);
X	fprintf(fp, "%c\n", key->left);
X	fprintf(fp, "%c\n", key->rotright);
X	fprintf(fp, "%c\n", key->rotleft);
X	fprintf(fp, "%c\n", key->drop);
X	fprintf(fp, "%c\n", key->togdisp);
X	fprintf(fp, "%c\n", key->togshad);
X	close(fp);
X
X	for (i=2; i<12; i++) {
X		mvaddstr(i,35,"++++++++++");
X		mvaddstr(23-i,35,"++++++++++");
X		csr_draw(2,35,21,44);
X	}
X	mvaddstr(11,35,"GAME SAVED");
X	csr_draw(11,35,11,44);
X
X	csr(23,0);
X	resetty();
X	exit(0);
X}
END_OF_FILE
if test 1925 -ne `wc -c <'save_game.c'`; then
    echo shar: \"'save_game.c'\" unpacked with wrong size!
fi
# end of 'save_game.c'
fi
if test -f 'score.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'score.c'\"
else
echo shar: Extracting \"'score.c'\" \(739 characters\)
sed "s/^X//" >'score.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: score.c														*/
X/* this is what keeps score												*/
X#include "tetris.h"
X
Xvoid score(final_row)
Xint final_row;
X{
X	points += current->pointv + 21 - final_row;
X	if (current->was_shown == 0)
X		points += level;
X	if (current->was_shadowed == 0)
X		points += level;
X	if (dropped_from)
X		points += final_row - dropped_from; 
X
X	move(0, 65);
X	printc("score: %7.7d", points);
X
X	csr_draw(0,65,0,79);
X}
END_OF_FILE
if test 739 -ne `wc -c <'score.c'`; then
    echo shar: \"'score.c'\" unpacked with wrong size!
fi
# end of 'score.c'
fi
if test -f 'score.tetris' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'score.tetris'\"
else
echo shar: Extracting \"'score.tetris'\" \(393 characters\)
sed "s/^X//" >'score.tetris' <<'END_OF_FILE'
X40144
Xpuzzled
XDo not go gently into that dark night.
X39458
Xlupin3
X-=/TetriSuicide/=-
X31758
Xjohnnyb
X-=[ Bloc - Head ]=-
X29403
Xclndria
XDon't be afraid...I don't [usually] bite 
X28322
Xentropy
Xdoofus
X28305
Xastarte
XGoddess of Fertility
X28275
Xlestat
XThe Vampire Lestat
X24746
Xgames
XMartin Heidegger
X22574
Xmmp
Xdoofus
X22188
Xbluelbo
XI can stop any time I want
X20330
Xserling
XRich Wilkman...Tetris Addict
END_OF_FILE
if test 393 -ne `wc -c <'score.tetris'`; then
    echo shar: \"'score.tetris'\" unpacked with wrong size!
fi
# end of 'score.tetris'
fi
if test -f 'set_level.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'set_level.c'\"
else
echo shar: Extracting \"'set_level.c'\" \(626 characters\)
sed "s/^X//" >'set_level.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: set_level.c
X** this decrements the interval timer everytime a new level is reached
X*/
X#include "tetris.h"
X
Xset_level()
X{
X	timer.it_interval.tv_usec = 500000 - (level * 1000 * DIFFICULTY);
X	timer.it_value.tv_usec = 500000 - (level * 1000 * DIFFICULTY);
X	setitimer(ITIMER_REAL, &timer, 0);
X}
END_OF_FILE
if test 626 -ne `wc -c <'set_level.c'`; then
    echo shar: \"'set_level.c'\" unpacked with wrong size!
fi
# end of 'set_level.c'
fi
if test -f 'setup_next.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'setup_next.c'\"
else
echo shar: Extracting \"'setup_next.c'\" \(1849 characters\)
sed "s/^X//" >'setup_next.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: setup_next.c                                                     */
X/*                                                                          */
X/* following a successful drop of a block this function will do all the     */
X/* house-keeping necessary to the creation of a new block.                  */
X/*                                                                          */
X#include "tetris.h"
X
Xvoid setup_next()
X{
X
X	int pow();
X
X	if (disp_next)
X		print_shape(next->shape, 17, 6, 
X				next->rot, ' '); /* erase the next shape */
X
X	bcopy(next, current, sizeof(struct shape));		 /* move next to current */
X
X	next->shape = random() % 7;
X	next->rot = random() % 4;
X	next->color = shape[next->shape].color;
X	next->offset = shape[next->shape].offset;
X	next->pointv = shape[next->shape].pointv[next->rot];
X	next->was_shown = (disp_next ? 1 : 0);
X
X	if (next->rot == 0 || next->rot == 2) {
X		next->width = shape[next->shape].width;
X		next->height = shape[next->shape].height;
X	}
X	if (next->rot == 1 || next->rot == 3) {
X		next->width = shape[next->shape].height;
X		next->height = shape[next->shape].width;
X	}
X
X	curx =  39 - ((current->offset & pow(2, 6 - (current->rot * 2))) ? 1 : 0);
X
X	cury = 2 - ((current->offset & pow(2, 7 - (current->rot * 2))) ? 1 : 0) -
X				current->height;
X
X	if (disp_next)
X		print_shape(next->shape, 17, 6, next->rot,
X						next->color);
X	print_shape(current->shape, curx, cury, current->rot,
X					current->color);
X	if (shadow == 1) {
X		current->was_shadowed = 1;
X		draw_shadow();
X	}
X}
END_OF_FILE
if test 1849 -ne `wc -c <'setup_next.c'`; then
    echo shar: \"'setup_next.c'\" unpacked with wrong size!
fi
# end of 'setup_next.c'
fi
if test -f 'tetris.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tetris.h'\"
else
echo shar: Extracting \"'tetris.h'\" \(3167 characters\)
sed "s/^X//" >'tetris.h' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: tetris.h                                                        */
X/*                                                                         */
X/* this is the header file, it does all the necessary includes, defines    */
X/* the necessary macros, and contains a lot of needed runtime data.        */
X#include <sys/file.h>
X#include <sys/time.h>
X#include <sys/types.h>      
X#include <sys/stat.h>
X#include <pwd.h>
X#include <signal.h>
X#include <stdio.h>
X#include <utmp.h>
X#include "csr.h"			
X
X#define LASTDATE		"2/23/89"
X#define VERSION			13
X
X#define HIGHSCOREFILE	"/usr/games/lib/tetris/score.tetris"
X#define MONITORFILE		"/dev/null"
X#define HELPFILE		"/usr/games/lib/tetris/help.tetris"
X#define MASTERUID		0
X#define DIFFICULTY		10
X
X#define NUMOFCOLORS		9	/* number of 'colors' available */
X#define xoffset		(current->offset & pow(2, 6 - (current->rot *2)))
X#define yoffset		(current->offset & pow(2, 7 - (current->rot *2)))
X#define MASK(sig)		(1 << ((sig) - 1))
X#define SIGHOLD(signo)		(sigblock(MASK(signo)))
X#define SIGRELSE(signo)		(sigsetmask(sigblock(0) &~ MASK(signo)))
X
Xchar keystr[10];
Xint addict;
Xint rubble;
Xint version;
Xint disp_next;              /* flag for the display next block feature (bug?)*/
Xint disp_tomb;              /* flag for the display tombstone feature (bug?)*/
Xint disp_high;              /* flag for the display high score feature (bug?)*/
Xint disp_open;              /* flag for the display open screen feature (bug?)*/
Xint shadow;              	/* flag for the shadowing feature (bug?)*/
Xint nowrite;				/* flag for nowrite option */
Xstruct stat *ttystat;		/* this hold the file perms of the user's tty */
Xint curx, cury; 			/* current block's x,y coords */
Xint points, level;			/* current score and level    */
Xint current_high;           /* current high score */
Xchar rcd_file[255];	        /* path to rc file */
Xint lines;					/* number of lines eaten	  */
Xint dropped_from;			/* flag to tell score function where fast drop
X							   came from									*/
Xint fast_drop;				/* flag for dropping blocks fast */
Xchar *user;
Xint  high_score[15];
Xchar high_user[15][8];
Xchar high_name[15][255];
Xchar username[100];
X
Xstruct shape_table {		/* this structure holds all the block defins */
X	int table[4][4];
X	int width;
X	int height;
X	int offset;
X	int pointv[4];
X	char color;
X	} shape[7];
X
Xstruct shape {				/* these are for quick reference      */
X	int shape;				/* do I know what I am doing? Nah.... */
X	int rot;
X	int width;
X	int height;
X	int offset;
X	int pointv;
X	char color;
X	int was_shown;
X	int was_shadowed;
X	} *current, *next;
X
Xstruct keystr {
X	char left;
X	char right;
X	char rotleft;
X	char rotright;
X	char drop;
X	char togdisp;
X	char togshad;
X	} *key; 
X
Xstruct itimerval timer, otimer;		/* these are for the interrupt timing */
Xstruct passwd *user_info;			/* user info (tricky names aren't they?) */
END_OF_FILE
if test 3167 -ne `wc -c <'tetris.h'`; then
    echo shar: \"'tetris.h'\" unpacked with wrong size!
fi
# end of 'tetris.h'
fi
if test -f 'tetris.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tetris.man'\"
else
echo shar: Extracting \"'tetris.man'\" \(3191 characters\)
sed "s/^X//" >'tetris.man' <<'END_OF_FILE'
X.TH TETRIS 1 "23 February 1989" "UNIX Programmer's Manual"
X.SH NAME
Xtetris - popular game of dropping blocks.
X.SH SYNOPSIS
X.B /usr/games/tetris
X[-] [-whotnbsa] [-L level] [-N name] [-O oblev] [-K keys]
X.SH DESCRIPTION
X.B Tetris
Xis played in real-time on a 10X20 board. Randomly selected shapes of 
Xfour contiguous blocks are dropped from the top of the board. The player
Xtries to rotate and move the blocks so that they form continuous
Xhorizontal rows. When a row is completed, it disappears. If the screen
Xfills up to the point that a shape cannot drop below the top of the screen,
Xthe game ends.
X.br
X.SH ARGUMENTS
X
XThe command line arguments are as follows:
X
X.B
X-
X- give summary of usage
X.br
X.B
Xw
X- makes you unwritable for duration of game
X.br
X.B
Xh
X- suppress printing of high score list
X.br
X.B
Xo
X- suppress opening screen selection box
X.br
X.B
Xt
X- display roguelike tombstone
X.br
X.B
Xn
X- turn off next block display
X.br
X.B
Xb
X- turn off shadowing
X.br
X.B
Xs
X- display high score list and exit
X.br
X.B
Xa
X- addict option, logs you out when game is over
X.br
X.B
XN
X.I [name] 
Xuse [name] for high score list (40 chars max), default to NAME environment.
X.br
X.B
XL
X.I [level]
X- start at [level] of difficulty (max starting level of 20)
X.br
X.B
XO
X.I [oblev]
X- generate [oblev]s of debris (max 13 levels of debris) 
X.br
X.B
XK
X.I [keys]
X- map control keys to [keys]
X.br
X
XTetris also checks for the environment variable TETRIS. The user can place
Xcommand line arguments into this variable to be used for every game.
X
X.br
X.SH COMMANDS
X
X.B h
X- move block left
X.br
X.B l
X- move block right
X.br
X.B j
X- rotate block counter-clockwise
X.br
X.B k
X- rotate block clockwise
X.br
X.B ?
X- online help 
X.br
X.B n
X- toggle next block display 
X.br
X.B b
X- toggle shadowing 
X.br
X.B space
X- drop block quickly 
X.br
X.B D
X- redefine keys 
X.br
X.B P
X- pause game 
X.br
X.B S
X- save game 
X.br
X.B Q
X- quit game 
X.br
X.SH DIAGNOSTICS
X.I Your terminal must have cursor movement capabilities: 
X.br
XThis is message from the cursor movement package informing you that
Xyour terminal is not sophisticated enough for tetris. In some cases, your
Xtermcap entry might be to blame.
X
X.br
X.I Panic!
X.br
XYou have been a naughty tetris player. You have tried to modify your
Xsave file and tetris is now going to punish you.
X.br
X.SH FILES
X.I /usr/games/lib/help.tetris
X.br
X.I /usr/games/lib/monitor.tetris
X.br
X.I /usr/games/lib/score.tetris
X.br
X.I ~/tetris.save
X.br
X.SH BUGS
X.br
XIn its current version (1.3) \s-2unix\*R\s+2 Tetris is too cpu intensive.
X
X.br
XThere are strange quirks that allow blocks to be rotated into one another.
X
X.br
XThe save game files are minimally secure at best.
X
X.br
XThe key mapping works but you have to give the keys in the proper order.
XThe implementation is very unforgiving.
X
X.br
XTetris was conceived by a soviet computer science student and is, therefore,
Xmost probably a communist plot.
X
X.SH AUTHOR
[email-masked]
X.br
X{...}!ucbvax!ucscc!ssyx!vespa
X.br
X.SH NOTES
XTetris is meant for free distribution. It is not to be licensed or sold
Xfor profit.
X
X.br
XAnyone who wishes a copy may have one.
X
X.br
XIn general, I would like to see distribution done in the philosophy
Xof the Free Software Foundation, a.k.a. the GNU project.
END_OF_FILE
if test 3191 -ne `wc -c <'tetris.man'`; then
    echo shar: \"'tetris.man'\" unpacked with wrong size!
fi
# end of 'tetris.man'
fi
if test -f 'useful.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'useful.c'\"
else
echo shar: Extracting \"'useful.c'\" \(813 characters\)
sed "s/^X//" >'useful.c' <<'END_OF_FILE'
X/*
X** written by adam margulies [email-masked]
X**                           {...}!ucbvax!ucscc!ssyx!vespa
X**
X** permission is granted to freely distribute this code provided that you:
X**
X** 1) don't charge for it
X** 2) leave my name and header on it
X** 3) clearly document your changes and place your name on them
X**
X*/
X/* Tetris: useful.c														 */
X/* these are functions that I find useful for all other function writing */
X#include "tetris.h"
X	
Xint pow(base, exponent)
Xint base, exponent;
X{
X	int tmp = 1;
X
X	if (exponent == 0)
X		return(1);
X
X	if (exponent == 1)
X		return(base);
X
X	while (exponent--)
X		tmp *= base;
X
X	return(tmp);
X}
X
Xvoid bfill(buf, len, ch)
Xchar *buf, ch;
Xint len;
X{
X	while(len--)
X		*buf++ = ch;
X}
X
Xvoid cont_hand() {
X	init_csr();
X	bfill(window0, sizeof(window0), ' ');
X	refresh();
X}
END_OF_FILE
if test 813 -ne `wc -c <'useful.c'`; then
    echo shar: \"'useful.c'\" unpacked with wrong size!
fi
# end of 'useful.c'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0