/***************************************************************************\
|*									   *|
|*  tt.h:	A version of Tetris to run on ordinary terminals,	   *|
|*		(ie., not needing a workstation, so should available	   *|
|*		to peasant Newwords+ users.				   *|
|*									   *|
|*  Author:	Mike Taylor (mirk@uk.ac.warwick.cs)			   *|
|*  Started:	Fri May 26 12:26:05 BST 1989				   *|
|*									   *|
\***************************************************************************/
/***************************************************************************\
|*									   *|
|*  The following macro, if defined, causes the exclusive high-score	   *|
|*  file-locking to be done using lockf(3) instead of the O_EXCL flag	   *|
|*  on open(2).	 This means that no temporary file need be created, and	   *|
|*  thus, that no write-permission is needed on a lockfile-directory.	   *|
|*  This should probably be used in preference to open(O_EXCL) when it	   *|
|*  exists and is bugless.  WARNING: on some machines, buggy versions	   *|
|*  of lockf(3) can crash the machine, (eg. Sun3/4s running SunOS 4.0.1)   *|
|*									   *|
\***************************************************************************/

#undef LOCKF			/* Use lockf(3) instead of open(O_EXCL) */

/***************************************************************************\
|*									   *|
|*  File in which high-scores will be stored.  I'm not gonna muck	   *|
|*  about encrypting them or anything, so you can either make tt	   *|
|*  setuid, or just run the risk of stupid people editing the high-	   *|
|*  score table by hand.						   *|
|*									   *|
\***************************************************************************/

#define LOCK_FILE	"/usr/local/etc/ttlock"
#define SCORE_FILE	"/usr/local/etc/ttscores"

/*-------------------------------------------------------------------------*/

#define NO_HISCORES	100	/* Size of high-score table */
#define NO_SHOWN	10	/* Default number to print */
#define LINELEN		160	/* Maximum length of a line of text */
#define NAMELEN		24	/* Multiple of four for struct-padding */
#define CODELEN		12	/* Multiple of four for struct-padding */

#define GAME_WIDTH	10	/* Number of squares across board */
#define GAME_DEPTH	20	/* Number of squares down board */
#define STAT_WIDTH	37	/* Number of characters for messages */

#define NO_PIECES	7	/* Number of different pieces */
#define NO_ORIENTS	4	/* Number of orientations possible */
#define NO_SQUARES	4	/* Max. number of squares per piece */
#define NO_DIMS		2	/* Number of dimensions of screen */

#define PI_EMPTY	-1	/* Position of board is empty */
#define PI_SQUARE	0	/* Square piece */
#define PI_LONG		1	/* Long piece */
#define PI_ELL1		2	/* L-shaped piece */
#define PI_ELL2		3	/* Backwards L-shaped piece */
#define PI_TEE		4	/* T-shaped piece */
#define PI_ESS1		5	/* S-shaped piece */
#define PI_ESS2		6	/* Backwards S-shaped piece */

/***************************************************************************\
|*									   *|
|*  The following #defines, (the LE_* ones) are local errors, in the	   *|
|*  sense of being local to this program, as distinct from the system	   *|
|*  errors, (ENOENT, EINTR and friends).  They should be used as exit	   *|
|*  statuses, as the first argument to die(), defined in utils.c	   *|
|*									   *|
\***************************************************************************/

#define LE_OK		0	/* No problems, me ole' fruit-bat */
#define LE_USAGE	1	/* Command-line syntax was wrong */
#define LE_ENV		2	/* Couldn't get environment variable */
#define LE_TERMCAP	3	/* Couldn't get a termcap entry */
#define LE_SCREEN	4	/* Screen was too small for game */
#define LE_SIGNAL	5	/* Signal(3) call failed */
#define LE_SELECT	6	/* Select(2) call failed */
#define LE_READ		7	/* Read(2) call failed */
#define LE_MALLOC	8	/* Couldn't allocate memory */
#define LE_LEVEL	9	/* User wanted to play on a silly level */
#define LE_OPEN		10	/* Open(2) call failed */
#define LE_STAT		11	/* {f,l,}stat(2) call failed */
#define LE_WRITE	12	/* write(2) call failed */
#define LE_GETUID	13	/* getuid(2) call failed */
#define LE_GETPW	14	/* getpwuid(3) call failed */

/***************************************************************************\
|*									   *|
|*  This is the structure of which the high-score table is composed.	   *|
|*  I'm gonna make everything a muliple of four bytes in an attempt	   *|
|*  to maintain file-compatibility between sun3s and 4s (and maybe	   *|
|*  other things, who knows?)  This is also why all the integers are	   *|
|*  long -- this helps to ensure that they will be four bytes long on	   *|
|*  most architectures, (ie. including some that have 2-byte integers)	   *|
|*  thus making struct-compatibility more likely.			   *|
|*									   *|
\***************************************************************************/

struct score_ent {
  char name[NAMELEN];		/* Name of player (from environment) */
  char code[CODELEN];		/* Code of player (from getpwuid()) */
  long int score;		/* Total score (5 for an "S" etc.) */
  long int no_pieces;		/* Number of pieces dropped in */
  long int no_levels;		/* Number of levels completed */
  long int game_level;		/* Number of free pieces at start */
};

/*-------------------------------------------------------------------------*/

extern int screen_depth;	/* To be calculated by termcap(3) */
extern int screen_width;	/* To be calculated by termcap(3) */
extern int so_gunk;		/* To be calculated by termcap(3) */
extern int in_curses;		/* Set to 1 after initialisation */
extern int rotate_backwards;	/* If set non-zero, rotate clockwise */
extern int no_hiscores;		/* Number of hi-scores in the table */
extern int game_level;		/* Number of free pieces */
extern int score;		/* Accumulated game score */
extern int no_pieces;		/* Number of pieces dropped so far */
extern int no_levels;		/* Number of levels filled & deleted */
extern char prog_name[LINELEN]; /* Will be the basename of argv[0] */
extern char user_name[NAMELEN]; /* From environment: TTNAME or NAME */
extern char user_code[CODELEN]; /* From getpwuid(getuid())->pw_name */
extern int board[GAME_DEPTH+4][GAME_WIDTH];
extern struct score_ent hi_scores[NO_HISCORES];

extern char tc_string[LINELEN]; /* Static, filled by termcap(3) */
extern char *so_str;		/* Points at things found by termcap(3) */
extern char *se_str;		/* Points at things found by termcap(3) */

/*-------------------------------------------------------------------------*/

extern void signal_die ();	/* When CTRL-C etc. is pressed */

/*-------------------------------------------------------------------------*/
/***************************************************************************\
|*									   *|
|*  The following macros will be defined if FD_ZERO is not defined by	   *|
|*  the system.  They simulate the behaviour of 4.3bsd's FD_ macros for	   *|
|*  4.2bsd machines, (ie. those running Berkeley UNIX, but of earlier	   *|
|*  issue than 4.3; also SunOS, issues earlier than 4.0.		   *|
|*									   *|
|*  This section added Fri Jun 23 20:18:20 BST 1989			   *|
|*  Written by Mike Taylor (mirk@uk.ac.warwick.cs)			   *|
|*									   *|
\***************************************************************************/

#ifndef FD_ZERO
#  define fd_set long int
#  define FD_ZERO(fds_ptr) *(fds_ptr) = 0
#  define FD_SET(fd, fds_ptr) *(fds_ptr) |= (1<<(fd))
#endif /* FD_ZERO */

/*-------------------------------------------------------------------------*/
