[comp.sources.x] v11i083: mosaic, Part01/01

tuna@kanchenjunga.LCS.MIT.EDU (Kirk 'UhOh' Johnson) (02/18/91)

Submitted-by: tuna@kanchenjunga.LCS.MIT.EDU (Kirk 'UhOh' Johnson)
Posting-number: Volume 11, Issue 83
Archive-name: mosaic/part01

moderator's note: This is the source to "mosaic", which is, as
the author describes, "an X11 game".  That's all it says.  The
README doesn't describe the game either.  I have not built or
run the program, so I have no idea what it does, how it works,
or even if it works (altho I'm sure it worked for the author :-).

dan

---------------- cut here
#!/bin/sh
# This is a shell archive (shar 3.32)
# made 01/31/1991 00:08 UTC by tuna@kanchenjunga
# Source directory /am/nanga-parbat/u2/tuna/src/mosaic
#
# existing files will NOT be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   4433 -r--r--r-- README
#    102 -r--r--r-- HISTORY
#    875 -r--r--r-- Imakefile
#   1157 -r--r--r-- Makefile.DIST
#   7160 -r--r--r-- mosaic.c
#   1606 -r--r--r-- mosaic.h
#    184 -r--r--r-- patchlevel.h
#  28139 -r--r--r-- x11.c
#   2766 -r--r--r-- x11.h
#   4792 -r--r--r-- mosaic.man
#     50 -rwxrwxrwx mosaic.scores
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= README ==============
if test X"$1" != X"-c" -a -f 'README'; then
	echo "File already exists: skipping 'README'"
else
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
X                README file for mosaic, version 1.0
X                Kirk Johnson
X                January 1991
X
X
XMANIFEST:
X
X    README              this file
X    Imakefile           for use with "imake"
X    Makefile.DIST       for use with "make"
X    mosaic.[ch]         non-X-related source code
X    x11.[ch]            X-related source code
X    mosaic.man          man page
X    mosaic.scores       prototype high score file
X
X
XINSTALLATION NOTES:
X
XMosaic can be built and installed "by hand", with "make", or with
X"imake". Brief instructions for each are provided below. If these
Xinstructions are somehow incorrect or deficient, please send me e-mail
Xat the address shown below.
X
X- To build mosaic "by hand":
X
X    (1) Compile the source file "mosaic.c", taking care to provide a
X        define for the absolute path of the high score file (see
X        "ABOUT THE HIGH SCORE FILE", below).
X
X    (2) Compile the source file "x11.c".
X
X    (3) Link the resulting object files with the X11 library to
X        produce an executable.
X
X    (4) Copy the executable and man page to whatever places are
X        appropriate for your environment. Copy "mosaic.scores" to path
X        you provided in step (1).
X
X    (5) Use "chmod a+rwx ..." or "chmod 777 ..." to enable global
X        read/write access for the copy of high scores file you made in
X        step (4).
X
X    On many systems, steps (1) through (3) might be accomplished with
X    something like:
X
X      cc -DScoreFile=\"/u/tuna/src/mosaic/mosaic.scores\" -c mosaic.c
X      cc -c x11.c
X      cc -o mosaic mosaic.o x11.o -lX11
X
X    (You should replace "/u/tuna/src/mosaic/mosaic.scores" with the
X    path you'll be using for the high score file in your system.)
X
X- To build mosaic with "make":
X
X    (1) Copy the distribution makefile "Makefile.DIST" to "Makefile".
X
X    (2) Edit the define for "ScoreFile" as appropriate for your local
X        environment. (Replace "/u/tuna/src/mosaic/mosaic.scores" with
X        the absolute path you want to use for the high score file; see
X        "ABOUT THE HIGH SCORE FILE", below.)
X
X    (3) Run "make all" to produce an executable.
X
X    (4) Copy the executable and man page to whatever places are
X        appropriate for your environment. Copy "mosaic.scores" to path
X        you provided in step (1).
X
X    (5) Use "chmod a+rwx ..." or "chmod 777 ..." to enable global
X        read/write access for the copy of high scores file you made in
X        step (4).
X
X- To build mosaic with "imake":
X
X    (0) I'm not much of an imake wizard, so I don't guarantee that
X        the following will work on your system. If you have trouble
X        building mosaic according to these directions, you may want to
X        resort to using "make" or building "by hand" according to the
X        directions given above.
X
X        On the other hand, if you _are_ an imake wizard and have
X        reasonable suggestions about how I could improve these
X        directions and/or the accompanying Imakefile, please send me
X        e-mail at the address shown below.
X
X    (1) Edit the provided "Imakefile"; replace the definition of
X        SCOREDIR with the name of the directory you'd like the high
X        score file to be installed in.
X
X    (2) Build a Makefile with "xmkmf". (If your system has "imake" but
X        not "xmkmf", you might try something like:
X
X          imake -DUseInstalled -I/usr/lib/X11/config
X
X        Read the "imake" man page or see your local imake wizard for
X        more info.)
X
X    (3) Run "make all" to produce an executable.
X
X    (4) Run "make install" to install the executable and the high
X        score file.
X
X    (5) Run "make install.man" to install the man page.
X
X
XABOUT THE HIGH SCORE FILE:
X
X    Mosaic keeps a list of high scores in a simple text file; all
X    users need to have read/write access to this file. You should take
X    care not to put the high score file in a place some users will not
X    have read/write access to.
X
X    After installing mosaic, you may want to double check that other
X    users can get at the high score file by having them play a game and
X    ensuring that their scores appear in the high score file.
X
X
XAUTHOR:
X
X    Mosaic was written by Kirk Johnson <tuna@athena.mit.edu>. It is
X    based on Joshua Klayman's PC/MS-DOS shareware game of the same
X    name. This version is a complete rewrite encompasing only the
X    basic functionality of the original.
X
X    Bug reports and suggestions are welcome.
SHAR_EOF
$TOUCH -am 0130190491 README &&
chmod 0444 README ||
echo "restore of README failed"
set `wc -c README`;Wc_c=$1
if test "$Wc_c" != "4433"; then
	echo original size 4433, current size $Wc_c
fi
fi
# ============= HISTORY ==============
if test X"$1" != X"-c" -a -f 'HISTORY'; then
	echo "File already exists: skipping 'HISTORY'"
else
echo "x - extracting HISTORY (Text)"
sed 's/^X//' << 'SHAR_EOF' > HISTORY &&
XRelease history for mosaic, version 1.0
X
X
X1.0             (January 1991)
X
X    Initial public release.
SHAR_EOF
$TOUCH -am 0130190491 HISTORY &&
chmod 0444 HISTORY ||
echo "restore of HISTORY failed"
set `wc -c HISTORY`;Wc_c=$1
if test "$Wc_c" != "102"; then
	echo original size 102, current size $Wc_c
fi
fi
# ============= Imakefile ==============
if test X"$1" != X"-c" -a -f 'Imakefile'; then
	echo "File already exists: skipping 'Imakefile'"
else
echo "x - extracting Imakefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Imakefile &&
X/**/################################################################
X/**/## begin configuration stuff                                  ##
X/**/## (see the README file for details)                          ##
X/**/################################################################
X
X       SCOREDIR = /u/tuna/src/mosaic
X
X/**/################################################################
X/**/## end configuration stuff                                    ##
X/**/################################################################
X
X      SCOREFILE = $(SCOREDIR)/mosaic.scores
X   INSTDATFLAGS = -m 0777
X
X         CFLAGS = -DScoreFile=\"$(SCOREFILE)\"
X
X           SRCS = mosaic.c x11.c
X           OBJS = mosaic.o x11.o
X        DEPLIBS = $(DEPXLIB)
XLOCAL_LIBRARIES = $(XLIB)
X
XComplexProgramTarget(mosaic)
XMakeDirectories(install, $(SCOREDIR))
XInstallNonExec(mosaic.scores, $(SCOREFILE))
SHAR_EOF
$TOUCH -am 0130190491 Imakefile &&
chmod 0444 Imakefile ||
echo "restore of Imakefile failed"
set `wc -c Imakefile`;Wc_c=$1
if test "$Wc_c" != "875"; then
	echo original size 875, current size $Wc_c
fi
fi
# ============= Makefile.DIST ==============
if test X"$1" != X"-c" -a -f 'Makefile.DIST'; then
	echo "File already exists: skipping 'Makefile.DIST'"
else
echo "x - extracting Makefile.DIST (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile.DIST &&
X################################################################
X## begin configuration stuff                                  ##
X## (see the README file for details)                          ##
X################################################################
X
X## to enable logging, define the symbol LOGGING and define
X## LogDir to be the absolute path of the log directory
X
X## ScoreFile - absolute path of the high score file location
X## (Edit this as appropriate for your local environment.)
X##
XDEFS	= -DScoreFile=\"/u/tuna/src/mosaic/mosaic.scores\"
X
X################################################################
X## end configuration stuff                                    ##
X################################################################
X
XRM	= /bin/rm
X
XCFLAGS	= $(DEFS)
X
XPROG	= mosaic
XSRCS 	= mosaic.c x11.c
XOBJS	= mosaic.o x11.o
XLIBS	= -lX11
X
XDIST	= README HISTORY Imakefile Makefile.DIST *.[ch] *.man mosaic.scores
X
Xall:		$(PROG)
X
X$(PROG):	$(OBJS)
X	$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS)
X
Xtarfile:
X	-$(RM) $(PROG).tar*
X	tar cvf $(PROG).tar $(DIST)
X	compress -v $(PROG).tar
X
Xsharfile:
X	-$(RM) $(PROG).shar*
X	shar -x -o $(PROG).shar $(DIST)
SHAR_EOF
$TOUCH -am 0130190491 Makefile.DIST &&
chmod 0444 Makefile.DIST ||
echo "restore of Makefile.DIST failed"
set `wc -c Makefile.DIST`;Wc_c=$1
if test "$Wc_c" != "1157"; then
	echo original size 1157, current size $Wc_c
fi
fi
# ============= mosaic.c ==============
if test X"$1" != X"-c" -a -f 'mosaic.c'; then
	echo "File already exists: skipping 'mosaic.c'"
else
echo "x - extracting mosaic.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > mosaic.c &&
X/*
X * mosaic.c
X * kirk johnson
X * october 1990
X */
X
X#include "mosaic.h"
X#include <X11/Xos.h>
X#include <pwd.h>
X
X#ifdef LOGGING
Xstatic FILE *logfile;
Xstatic void  OpenLogFile();
X#endif
X
XWord tile[NTiles];		/* the board */
XWord piece[NPieces];		/* the "deck" of pieces */
XWord nextpiece;			/* index into the deck */
X
XWord size[NTiles];		/* score data structures */
XWord parent[NTiles];
X
XWord tscore[3];			/* total score */
XWord pscore[3];			/* last piece score */
XWord remain[3];			/* tiles remaining */
X
XNameAndScore highscore[NHighScores];
X
X
Xmain(argc, argv)
X     int    argc;
X     char **argv;
X{
X  ReadHighScores();
X  InitGame();
X  InitDisplay(argc, argv);
X#ifdef LOGGING
X  OpenLogFile();
X#endif
X  MainLoop();
X}
X
X
Xvoid InitGame()
X{
X  int i, j, k, l;
X  int idx, swap;
X
X  /* randomize */
X  srandom((int) time(NULL));
X
X  /* clear the board */
X  for (i=0; i<NTiles; i++)
X    tile[i] = 0;
X
X  /* set up deck */
X  idx = 0;
X  for (i=1; i<=3; i++)
X    for (j=1; j<=3; j++)
X      for (k=1; k<=3; k++)
X	for (l=1; l<=3; l++)
X	  piece[idx++] = (i<<6) | (j<<4) | (k<<2) | (l<<0);
X  
X  /* shuffle */
X  for (i=0; i<1000; i++)
X  {
X    idx  = random() % NPieces;
X    swap = piece[idx];
X    piece[idx] = piece[0];
X    piece[0]   = swap;
X  }
X  nextpiece = 0;
X
X  /* clear score data structures */
X  for (i=0; i<NTiles; i++)
X  {
X    size[i]   = 1;
X    parent[i] = i;
X  }
X
X  for (i=0; i<3; i++)
X  {
X    tscore[i] = 0;
X    pscore[i] = 0;
X    remain[i] = (NPieces * 4) / 3;
X  }
X}
X
X
Xvoid QuitGame()
X{
X  exit(0);
X}
X
X
Xint DropPiece(r, c, p)
X     int  r, c;
X     Word p;
X{
X  int  idx;
X  Word type;
X  Word nscore[3];
X
X  idx = r * BoardSize + c;
X  
X  /* check for illegal move */
X  if ((tile[idx] != 0) ||
X      (tile[idx+1] != 0) ||
X      (tile[idx+BoardSize] != 0) ||
X      (tile[idx+BoardSize+1] != 0))
X    return 0;
X
X  /* place the piece */
X  type = p & 0x03;
X  tile[idx] = type;
X  remain[type-1] -= 1;
X  p >>= 2;
X
X  type = p & 0x03;
X  tile[idx+1] = type;
X  remain[type-1] -= 1;
X  p >>= 2;
X
X  type = p & 0x03;
X  tile[idx+BoardSize] = type;
X  remain[type-1] -= 1;
X  p >>= 2;
X
X  type = p & 0x03;
X  tile[idx+BoardSize+1] = p & 0x03;
X  remain[type-1] -= 1;
X
X  /* update the score */
X  UpdateAndScore(r, c, nscore);
X  for (idx=0; idx<3; idx++)
X  {
X    pscore[idx] = nscore[idx] - tscore[idx];
X    tscore[idx] = nscore[idx];
X  }
X
X  /* redraw */
X  drawTile(r++, c);
X  drawTile(r, c++);
X  drawTile(r--, c);
X  drawTile(r, c--);
X  drawController();
X  drawScore();
X
X  return 1;
X}
X
X
Xvoid UpdateAndScore(r, c, score)
X     int  r, c;
X     Word score[];
X{
X  int i;
X
X  i = r * BoardSize + c;
X
X  PossiblyMerge(i, i+1);
X  PossiblyMerge(i+BoardSize, i+BoardSize+1);
X
X  PossiblyMerge(i, i+BoardSize);
X  PossiblyMerge(i+1, i+BoardSize+1);
X
X  if (c >= 1)
X  {
X    PossiblyMerge(i, i-1);
X    PossiblyMerge(i+BoardSize, i+BoardSize-1);
X  }
X
X  if (r >= 1)
X  {
X    PossiblyMerge(i, i-BoardSize);
X    PossiblyMerge(i+1, i-BoardSize+1);
X  }
X
X  if (c <= (BoardSize-3))
X  {
X    PossiblyMerge(i+1, i+2);
X    PossiblyMerge(i+BoardSize+1, i+BoardSize+2);
X  }
X
X  if (r <= (BoardSize-3))
X  {
X    PossiblyMerge(i+BoardSize, i+(2*BoardSize));
X    PossiblyMerge(i+BoardSize+1, i+(2*BoardSize)+1);
X  }
X
X  /* compute the new score */
X  for (i=0; i<3; i++)
X    score[i] = 0;
X  for (i=0; i<NTiles; i++)
X    if ((tile[i] != 0) && (parent[i] == i))
X      score[tile[i]-1] += size[i] * size[i];
X}
X
X
Xvoid PossiblyMerge(i, j)
X     int i, j;
X{
X  Word irep;
X  Word jrep;
X  Word scan;
X
X  /* tiles are not the same color */
X  if (tile[i] != tile[j]) return;
X
X  /* find i's rep */
X  irep = i;
X  while (parent[irep] != irep)
X    irep = parent[irep];
X
X  /* compress path from i to irep */
X  scan = i;
X  while (parent[scan] != scan)
X  {
X    scan = parent[scan];
X    parent[scan] = irep;
X  }
X
X  /* find j's rep */
X  jrep = j;
X  while (parent[jrep] != jrep)
X    jrep = parent[jrep];
X
X  /* compress path from j to jrep */
X  scan = j;
X  while (parent[scan] != scan)
X  {
X    scan = parent[scan];
X    parent[scan] = jrep;
X  }
X
X  /* tiles are already in the same set */
X  if (irep == jrep) return;
X
X  /* merge the sets */
X  if (size[irep] > size[jrep])
X  {
X    parent[jrep] = irep;
X    size[irep]  += size[jrep];
X  }
X  else
X  {
X    parent[irep] = jrep;
X    size[jrep]  += size[irep];
X  }
X}
X
X
Xvoid AutoPlay()
X{
X  int r, c;
X
X  while (nextpiece < NPieces)
X  {
X    do
X    {
X      r = random() % (BoardSize-1);
X      c = random() % (BoardSize-1);
X    }
X    while (!DropPiece(r, c, piece[nextpiece]));
X    
X    nextpiece += 1;
X    drawNext();
X
X    if (nextpiece == NPieces)
X      CheckHighScore();
X  }
X}
X
X
Xvoid ReadHighScores()
X{
X  int   i;
X  FILE *s;
X
X  s = fopen(ScoreFile, "r");
X  if (s == NULL)
X  {
X    warning("unable to open score file; creating new one");
X
X    for (i=0; i<NHighScores; i++)
X    {
X      strcpy(highscore[i].uname, ".");
X      highscore[i].score = -1;
X    }
X
X    s = fopen(ScoreFile, "w");
X    if (s == NULL)
X      fatal("unable to create score file");
X
X    WriteHighScores();
X    fclose(s);
X
X    if (chmod(ScoreFile, 0777) != 0)
X    {
X      unlink(ScoreFile);
X      fatal("unable to set score file mode");
X    }
X  }
X  else
X  {
X    for (i=0; i<NHighScores; i++)
X      if (fscanf(s, "%s %d",
X		 highscore[i].uname, &highscore[i].score) != 2)
X	fatal("incomplete score file read");
X    fclose(s);
X  }
X}
X
X
Xvoid WriteHighScores()
X{
X  int   i;
X  FILE *s;
X  
X  s = fopen(ScoreFile, "w");
X  if (s == NULL)
X    fatal("unable to open score file");
X
X  for (i=0; i<NHighScores; i++)
X    fprintf(s, "%s %d\n", highscore[i].uname, highscore[i].score);
X
X  fclose(s);
X}
X
X
Xvoid CheckHighScore()
X{
X  int   i;
X  int   score;
X  char *uname;
X
X  uname = getpwuid(getuid())->pw_name;
X  score = tscore[0] + tscore[1] + tscore[2];
X
X  /*
X   * note that we don't actually try to do any locking of
X   * the high score file during this critical section ...
X   */
X
X  ReadHighScores();
X  
X  for (i=0; i<NHighScores; i++)
X    if (strcmp(highscore[i].uname, uname) == 0)
X      break;
X
X  if (i == NHighScores)
X    i = NHighScores - 1;
X
X  if (score > highscore[i].score)
X  {
X    while ((i > 0) && (score > highscore[i-1].score))
X    {
X      strcpy(highscore[i].uname, highscore[i-1].uname);
X      highscore[i].score = highscore[i-1].score;
X      i -= 1;
X    }
X    strcpy(highscore[i].uname, uname);
X    highscore[i].score = score;
X
X    WriteHighScores();
X  }
X  
X  drawHighScores();
X
X#ifdef LOGGING
X  /*
X   * because we don't catch this and die when we open the file; add
X   * the check here. ah well.
X   */
X  if (logfile != NULL)
X  {
X    putc(1, logfile);
X    fflush(logfile);
X  }
X#endif
X}
X
X
Xwarning(msg)
X     char *msg;
X{
X  fflush(stdout);
X  fprintf(stderr, "%s: warning! %s\n", AppName, msg);
X  fflush(stderr);
X}
X
X
Xfatal(msg)
X     char *msg;
X{
X  fflush(stdout);
X  fprintf(stderr, "%s: %s\n", AppName, msg);
X  exit(1);
X}
X
X
X#ifdef LOGGING
Xstatic void OpenLogFile()
X{
X  char  hostname[256];
X  char  logname[256];
X
X  if (gethostname(hostname, 256) != 0)
X  {
X#ifdef DEBUG
X    warning("unable to get hostname");
X#endif      
X    return;
X  }
X  
X  sprintf(logname, "%s/%08X.%s.%d", LogDir, time(NULL), hostname, getuid());
X  logfile = fopen(logname, "w");
X  if (logfile == NULL)
X  {
X#ifdef DEBUG
X    warning("problems opening logfile");
X#endif      
X    return;
X  }
X}
X#endif
SHAR_EOF
$TOUCH -am 0130190491 mosaic.c &&
chmod 0444 mosaic.c ||
echo "restore of mosaic.c failed"
set `wc -c mosaic.c`;Wc_c=$1
if test "$Wc_c" != "7160"; then
	echo original size 7160, current size $Wc_c
fi
fi
# ============= mosaic.h ==============
if test X"$1" != X"-c" -a -f 'mosaic.h'; then
	echo "File already exists: skipping 'mosaic.h'"
else
echo "x - extracting mosaic.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > mosaic.h &&
X/*
X * mosaic.h
X * kirk johnson
X * october 1990
X */
X
X#ifndef _MOSAIC_H_
X#define _MOSAIC_H_
X
X#include <stdio.h>
X
X/* #define DEBUG */
X
X#define AppName   "mosaic"
X
X#define BoardSize (24)		/* width, in tiles */
X#define NPieces   (81)		/* # pieces per game */
X
X#define NTiles (BoardSize*BoardSize)
X
X#define MaxUnameLen  (8)	/* eight chars per uname, max */
X#define MaxScoreLen  (5)	/* five chars per score, max */
X#define NHighScores  (10)	/* # of high scores kept */
X#define NHelpLines   (10)	/* # of lines in help window */
X
X#define MaxPossibleScore  "34992"
X
X
Xtypedef unsigned short Word;
X
Xtypedef struct
X{
X  char uname[MaxUnameLen+1];	/* username */
X  int  score;			/* score */
X} NameAndScore;
X
Xextern void InitGame();
Xextern void QuitGame();
Xextern int  DropPiece();
Xextern void UpdateAndScore();
Xextern void PossiblyMerge();
Xextern void AutoPlay();
Xextern void ReadHighScores();
Xextern void WriteHighScores();
Xextern void ReadHighScores();
Xextern void CheckHighScore();
X
Xextern void InitDisplay();
Xextern void MainLoop();
Xextern void drawBoard();
Xextern void drawHelp();
Xextern void drawTile();
Xextern void drawController();
Xextern void drawNext();
Xextern void drawTitle();
Xextern void drawScore();
Xextern void drawHighScores();
Xextern void drawAll();
X
Xextern Word tile[NTiles];	/* the board */
Xextern Word piece[NPieces];	/* the "deck" of pieces */
Xextern Word nextpiece;		/* index into the deck */
X
Xextern Word tscore[3];		/* total score */
Xextern Word pscore[3];		/* last piece score */
Xextern Word remain[3];		/* tiles remaining */
X
Xextern NameAndScore highscore[NHighScores];
X
X#endif /* _MOSAIC_H_ */
SHAR_EOF
$TOUCH -am 0130190491 mosaic.h &&
chmod 0444 mosaic.h ||
echo "restore of mosaic.h failed"
set `wc -c mosaic.h`;Wc_c=$1
if test "$Wc_c" != "1606"; then
	echo original size 1606, current size $Wc_c
fi
fi
# ============= patchlevel.h ==============
if test X"$1" != X"-c" -a -f 'patchlevel.h'; then
	echo "File already exists: skipping 'patchlevel.h'"
else
echo "x - extracting patchlevel.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
X/*
X * patchlevel.h
X * kirk johnson
X * january 1991
X */
X
X#ifndef _PATCHLEVEL_H_
X#define _PATCHLEVEL_H_
X
X#define MajorVersion  (1)
X#define MinorVersion  (0)
X
X#endif /* _PATCHLEVEL_H_ */
SHAR_EOF
$TOUCH -am 0130190491 patchlevel.h &&
chmod 0444 patchlevel.h ||
echo "restore of patchlevel.h failed"
set `wc -c patchlevel.h`;Wc_c=$1
if test "$Wc_c" != "184"; then
	echo original size 184, current size $Wc_c
fi
fi
# ============= x11.c ==============
if test X"$1" != X"-c" -a -f 'x11.c'; then
	echo "File already exists: skipping 'x11.c'"
else
echo "x - extracting x11.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > x11.c &&
X/*
X * x11.c
X * kirk johnson
X * october 1990
X */
X
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X#include "mosaic.h"
X#include "x11.h"
X#include "patchlevel.h"
X
X#define BufSize       (256)
X
X#define BoundVarVal(var, min, max) \
X{                                  \
X  if ((var) < (min))               \
X    (var) = (min);                 \
X  else if ((var) > (max))          \
X    (var) = (max);                 \
X}
X
Xtypedef unsigned long Pixel;
Xtypedef XFontStruct   XFS;
X
Xstatic void   GetDisplayName();
Xstatic void   GetResourceOptions();
Xstatic int    IsTrue();
Xstatic char  *strdup();
Xstatic void   GetCmdLineOptions();
Xstatic void   Help();
Xstatic void   doKey();
Xstatic void   doMotion();
Xstatic void   doBoardExpose();
Xstatic void   doHelpExpose();
Xstatic void   doNextExpose();
Xstatic void   doMainExpose();
Xstatic void   doHighExpose();
Xstatic void   doButtonPress();
Xstatic Pixel  GetColor();
Xstatic Window GetWindow();
Xstatic Pixmap MakePixmap();
Xstatic void   SetCursor();
Xstatic void   TopWindowStuff();
Xstatic void   AddEventHandler();
Xstatic void (*GetEventHandler())();
X
Xstatic char  buf[BufSize];
Xstatic char *TileBits[4];
X
Xstatic char *dpyname;		/* display name */
Xstatic int   mono;		/* mono mode flag */
Xstatic int   solid;		/* solid mode flag */
Xstatic int   expert;		/* expert mode flag */
Xstatic int   gwidth;		/* gutter width */
Xstatic int   bwidth;		/* border width */
Xstatic char *fgname;		/* fg color name */
Xstatic char *bgname;		/* bg color name */
Xstatic char *bdname;		/* border color name */
Xstatic char *cname[4];		/* tile color names */
Xstatic char *fntname;		/* font name */
X
Xstatic Display *dpy;		/* display connection */
Xstatic int      scrn;		/* screen number */
Xstatic Window   root;		/* root window */
Xstatic Visual  *visl;		/* visual */
Xstatic Colormap cmap;		/* colormap */
Xstatic int      dpth;		/* display depth */
Xstatic GC       gc;		/* graphics context */
X
Xstatic Pixel  fore;		/* foreground color */
Xstatic Pixel  back;		/* background color */
Xstatic Pixel  brdr;		/* border color */
Xstatic Pixel  tilec[4];		/* tile colors */
Xstatic Pixmap tilep[4];		/* tile pixmaps */
Xstatic XFS   *font;		/* text font */
X
Xstatic Window mainw;		/* main window */
Xstatic Window boardw;		/* board window */
Xstatic Window helpw;		/* help window */
Xstatic Window nextw;		/* next piece window */
Xstatic Window scoresw;		/* high scores window */
X
Xstatic int crow = 0;		/* controller position */
Xstatic int ccol = 0;
X
Xstatic int scoresvis;		/* high scores visible? */
Xstatic int helpvis;		/* help window visible? */
X
Xstatic int swidth;		/* width of score text area */
Xstatic int hswidth;		/* width of high score window */
X
X
Xvoid InitDisplay(argc, argv)
X     int    argc;
X     char **argv;
X{
X  int    i;
X  int    w, h;
X  int    x, y;
X
X  /* set standard defaults */
X  dpyname  = NULL;		/* default to DISPLAY */
X  expert   = False;		/* default to novice mode */
X  mono     = False;		/* default to color (if possible) */
X  solid    = False;		/* default to patterned tiles */
X  gwidth   = DfltGutterWidth;	/* gutter width */
X  bwidth   = DfltBorderWidth;	/* border width */
X  fgname   = DfltForeName;	/* foreground color name */
X  bgname   = DfltBackName;	/* background color name */
X  bdname   = DfltBrdrName;	/* border color name */
X  cname[0] = DfltC0Name;	/* color 0 name */
X  cname[1] = DfltC1Name;	/* color 1 name */
X  cname[2] = DfltC2Name;	/* color 2 name */
X  cname[3] = DfltC3Name;	/* color 3 name */
X  fntname  = DfltFontName;	/* font name */
X
X  GetDisplayName(argc, argv);
X
X  /* general X11 setup */
X  dpy = XOpenDisplay(dpyname);
X  if (dpy == NULL)
X  {
X    sprintf(buf, "unable to open display \"%s\"", dpyname);
X    fatal(buf);
X  }
X  scrn = DefaultScreen(dpy);
X  root = RootWindow(dpy, scrn);
X  visl = DefaultVisual(dpy, scrn);
X  cmap = DefaultColormap(dpy, scrn);
X  dpth = DefaultDepth(dpy, scrn);
X
X  GetResourceOptions();
X
X  /*
X   * if running with a StaticGray or GrayScale
X   * display class, default to mono mode
X   */
X  switch (visl->class)
X  {
X  case StaticGray:
X  case GrayScale:
X    mono = True;
X    break;
X  }
X
X  GetCmdLineOptions(argc, argv);
X
X  /* check for mono mode */
X  if (mono)
X  {
X    bdname = fgname;
X    for (i=0; i<4; i++)
X      cname[i] = fgname;
X  }
X
X#ifdef DEBUG
X  /* debug: color names */
X  fflush(stdout);
X  fprintf(stderr, "%s: color names\n", AppName);
X  fprintf(stderr, "  fgname %s\n", fgname);
X  fprintf(stderr, "  bgname %s\n", bgname);
X  fprintf(stderr, "  bdname %s\n", bdname);
X  fprintf(stderr, "  c0name %s\n", cname[0]);
X  fprintf(stderr, "  c1name %s\n", cname[1]);
X  fprintf(stderr, "  c2name %s\n", cname[2]);
X  fprintf(stderr, "  c3name %s\n", cname[3]);
X  fprintf(stderr, "\n");
X  fflush(stderr);
X#endif /* DEBUG */
X
X  /* color allocation */
X  fore = GetColor(fgname);
X  back = GetColor(bgname);
X  brdr = GetColor(bdname);
X  for (i=0; i<4; i++)
X    tilec[i] = GetColor(cname[i]);
X
X  /* graphics context */
X  gc = XCreateGC(dpy, root, 0, NULL);
X  XSetState(dpy, gc, fore, back, GXcopy, AllPlanes);
X
X  /* select the tile patterns */
X  if (solid)
X  {
X    TileBits[0] = zerobits;
X    TileBits[1] = solidbits;
X    TileBits[2] = solidbits;
X    TileBits[3] = solidbits;
X  }
X  else
X  {
X    TileBits[0] = zerobits;
X    TileBits[1] = onebits;
X    TileBits[2] = twobits;
X    TileBits[3] = threebits;
X  }
X
X  /* build the tiles */
X  for (i=0; i<4; i++)
X    tilep[i] = MakePixmap(TileBits[i], TileSize, TileSize, tilec[i], back);
X
X  /* fonts */
X  font = XLoadQueryFont(dpy, fntname);
X  if (font == NULL)
X  {
X    sprintf(buf, "unable to load font \"%s\"", fntname);
X    fatal(buf);
X  }
X
X  swidth  = XTextWidth(font, MaxPossibleScore, strlen(MaxPossibleScore));
X  swidth += TileSize + (gwidth*4);
X
X  /* main window */
X  w  = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
X  h  = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
X  w += gwidth + swidth;
X  h += gwidth + font->ascent + font->descent;
X  mainw = GetWindow(root, 0, 0, w, h, bwidth);
X  SetCursor(mainw, MainCurs);
X  XSelectInput(dpy, mainw, PointerMotionMask|KeyPressMask|ExposureMask);
X  AddEventHandler(mainw, MotionNotify, doMotion);
X  AddEventHandler(mainw, KeyPress, doKey);
X  AddEventHandler(mainw, Expose, doMainExpose);
X
X  /* playing board window */
X  x = gwidth;
X  y = gwidth;
X  w = (gwidth*2) + (TileSize*BoardSize);
X  h = (gwidth*2) + (TileSize*BoardSize);
X  boardw = GetWindow(mainw, x, y, w, h, bwidth);
X  SetCursor(boardw, BoardCurs);
X  XSelectInput(dpy, boardw, ExposureMask|ButtonPressMask);
X  AddEventHandler(boardw, Expose, doBoardExpose);
X  AddEventHandler(boardw, ButtonPress, doButtonPress);
X  XMapWindow(dpy, boardw);
X
X  /* help window */
X  w = (TileSize*(BoardSize-6)) + (gwidth*2);
X  h = NHelpLines*(font->ascent + font->descent) + (gwidth*2);
X  x = ((TileSize*BoardSize + gwidth*2) - (w + bwidth*2)) / 2;
X  y = ((TileSize*BoardSize + gwidth*2) - (h + bwidth*2)) / 2;
X  helpw = GetWindow(boardw, x, y, w, h, bwidth);
X  XSelectInput(dpy, helpw, ExposureMask);
X  AddEventHandler(helpw, Expose, doHelpExpose);
X
X  /* if we're in "expert" mode, don't map the silly help window initially */
X  if (expert)
X  {
X    helpvis = False;
X  }
X  else
X  {
X    XMapWindow(dpy, helpw);
X    helpvis = True;
X  }
X
X  /* next piece window */
X  x = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
X  y = gwidth;
X  w = (gwidth*2) + (TileSize*2);
X  h = (gwidth*2) + (TileSize*2);
X  nextw = GetWindow(mainw, x, y, w, h, bwidth);
X  XSelectInput(dpy, nextw, ExposureMask);
X  AddEventHandler(nextw, Expose, doNextExpose);
X  XMapWindow(dpy, nextw);
X
X  /* scores window */
X  hswidth  = XTextWidth(font, HighScoreTitle, strlen(HighScoreTitle));
X  hswidth += 2*gwidth;
X  w  = font->max_bounds.width * MaxUnameLen;
X  w += XTextWidth(font, MaxPossibleScore, strlen(MaxPossibleScore));
X  w += 3*gwidth;
X  if (hswidth > w)
X    w = hswidth;
X  else
X    hswidth = w;
X  h = (NHighScores+2)*(font->ascent + font->descent) + 2*gwidth;
X  scoresw = GetWindow(root, 0, 0, w, h, bwidth);
X  SetCursor(scoresw, MainCurs);
X  XSelectInput(dpy, scoresw, KeyPressMask|ExposureMask);
X  AddEventHandler(scoresw, KeyPress, doKey);
X  AddEventHandler(scoresw, Expose, doHighExpose);
X  scoresvis = False;
X
X  /* various magic incantations (window manager) */
X  TopWindowStuff(mainw, MainWindowName);
X  TopWindowStuff(scoresw, ScoresWindowName);
X
X  /* map the main window */
X  XMapWindow(dpy, mainw);
X}
X
X
Xstatic void GetDisplayName(argc, argv)
X     int    argc;
X     char **argv;
X{
X  int i;
X
X  /* get display name from command line */ 
X  for (i=1; i<argc; i++)
X    if (strcmp(argv[i], "-display") == 0)
X    {
X      i += 1;
X      if (i < argc)
X	dpyname = argv[i];
X      else
X	Help("no display arg provided");
X    }
X}
X
X
Xstatic void GetResourceOptions()
X{
X  char *tmp;
X
X  tmp = XGetDefault(dpy, AppName, "Mono");
X  if (tmp != NULL)
X    mono = IsTrue(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Solid");
X  if (tmp != NULL)
X    solid = IsTrue(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Expert");
X  if (tmp != NULL)
X    expert = IsTrue(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "GutterWidth");
X  if (tmp != NULL)
X  {
X    sscanf(tmp, "%d", &gwidth);
X    if (gwidth < 0)
X      fatal("gutterwidth must be non-negative");
X  }
X  
X  tmp = XGetDefault(dpy, AppName, "BorderWidth");
X  if (tmp != NULL)
X  {
X    sscanf(tmp, "%d", &bwidth);
X    if (bwidth < 0)
X      fatal("borderwidth must be non-negative");
X  }
X  
X  tmp = XGetDefault(dpy, AppName, "Foreground");
X  if (tmp != NULL)
X    fgname = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Background");
X  if (tmp != NULL)
X    bgname = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "BorderColor");
X  if (tmp != NULL)
X    bdname = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Color0");
X  if (tmp != NULL)
X    cname[0] = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Color1");
X  if (tmp != NULL)
X    cname[1] = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Color2");
X  if (tmp != NULL)
X    cname[2] = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Color3");
X  if (tmp != NULL)
X    cname[3] = strdup(tmp);
X
X  tmp = XGetDefault(dpy, AppName, "Font");
X  if (tmp != NULL)
X    fntname = strdup(tmp);
X}
X
X
Xstatic int IsTrue(s)
X     char *s;
X{
X  return ((strcasecmp(s, "true") == 0) ||
X	  (strcasecmp(s, "on") == 0) ||
X	  (strcasecmp(s, "yes") == 0));
X}
X
X
Xstatic char *strdup(s)
X     char *s;
X{
X  char *rslt;
X
X  rslt = (char *) malloc(sizeof(char) * (strlen(s) + 1));
X  if (rslt == NULL)
X    fatal("unable to malloc");
X
X  strcpy(rslt, s);
X
X  return rslt;
X}
X
X
Xstatic void GetCmdLineOptions(argc, argv)
X     int    argc;
X     char **argv;
X{
X  int i;
X
X  /* get options from command line */
X  for (i=1; i<argc; i++)
X    if (strcmp(argv[i], "-display") == 0)
X    {
X      /* already got the display name */
X      i += 1;
X    }
X    else if (strcmp(argv[i], "-expert") == 0)
X    {
X      /* run in "expert" mode */
X      expert = True;
X    }
X    else if (strcmp(argv[i], "-color") == 0)
X    {
X      /* try to use colors */
X      mono = False;
X    }
X    else if (strcmp(argv[i], "-mono") == 0)
X    {
X      /* skip the colors */
X      mono = True;
X    }
X    else if (strcmp(argv[i], "-patterns") == 0)
X    {
X      /* use patterned tiles */
X      solid = False;
X    }
X    else if (strcmp(argv[i], "-solid") == 0)
X    {
X      /* use solid tiles */
X      solid = True;
X    }
X    else if (strcmp(argv[i], "-gw") == 0)
X    {
X      /* get gutter width from next arg */
X      i += 1;
X      if (i < argc)
X	sscanf(argv[i], "%d", &gwidth);
X      else
X	Help("no gutterwidth arg provided");
X
X      /* ensure the gutter width is non-negative */
X      if (gwidth < 0)
X	fatal("gutterwidth must be non-negative");
X    }
X    else if (strcmp(argv[i], "-bw") == 0)
X    {
X      /* get border width from next arg */
X      i += 1;
X      if (i < argc)
X	sscanf(argv[i], "%d", &bwidth);
X      else
X	Help("no borderwidth arg provided");
X
X      /* ensure the border width is non-negative */
X      if (bwidth < 0)
X	fatal("borderwidth must be non-negative");
X    }
X    else if (strcmp(argv[i], "-fg") == 0)
X    {
X      /* get foreground color name from next arg */
X      i += 1;
X      if (i < argc)
X	fgname = argv[i];
X      else
X	Help("no foreground arg provided");
X    }
X    else if (strcmp(argv[i], "-bg") == 0)
X    {
X      /* get background color name from next arg */
X      i += 1;
X      if (i < argc)
X	bgname = argv[i];
X      else
X	Help("no background arg provided");
X    }
X    else if (strcmp(argv[i], "-bd") == 0)
X    {
X      /* get border color name from next arg */
X      i += 1;
X      if (i < argc)
X	bdname = argv[i];
X      else
X	Help("no bordercolor arg provided");
X    }
X    else if (strcmp(argv[i], "-c0") == 0)
X    {
X      /* get color 0 name from next arg */
X      i += 1;
X      if (i < argc)
X	cname[0] = argv[i];
X      else
X	Help("no color0 arg provided");
X    }
X    else if (strcmp(argv[i], "-c1") == 0)
X    {
X      /* get color 1 name from next arg */
X      i += 1;
X      if (i < argc)
X	cname[1] = argv[i];
X      else
X	Help("no color1 arg provided");
X    }
X    else if (strcmp(argv[i], "-c2") == 0)
X    {
X      /* get color 2 name from next arg */
X      i += 1;
X      if (i < argc)
X	cname[2] = argv[i];
X      else
X	Help("no color2 arg provided");
X    }
X    else if (strcmp(argv[i], "-c3") == 0)
X    {
X      /* get color 3 name from next arg */
X      i += 1;
X      if (i < argc)
X	cname[3] = argv[i];
X      else
X	Help("no color3 arg provided");
X    }
X    else if (strcmp(argv[i], "-fn") == 0)
X    {
X      /* get font name from next arg */
X      i += 1;
X      if (i < argc)
X	fntname = argv[i];
X      else
X	Help("no font arg provided");
X    }
X    else if (strcmp(argv[i], "-help") == 0)
X    {
X      Help(NULL);
X    }
X    else
X    {
X      sprintf(buf, "unknown option: %s", argv[i]);
X      Help(buf);
X    }
X}
X
X
Xstatic void Help(msg)
X     char *msg;
X{
X  if (msg != NULL)
X    fprintf(stderr, "\n%s\n", msg);
X  else
X    fprintf(stderr, "\n%s (v %d.%d)\n", AppName, MajorVersion, MinorVersion);
X
X  fprintf(stderr, "\ncommand line options:\n");
X  fprintf(stderr, "  -help           print this message\n");
X  fprintf(stderr, "  -display <d>    use display <d>\n");
X  fprintf(stderr, "  -expert         don't show quick help initially\n");
X  fprintf(stderr, "  -color          run in color mode\n");
X  fprintf(stderr, "  -mono           run in mono mode\n");
X  fprintf(stderr, "  -patterns       use patterned tiles\n");
X  fprintf(stderr, "  -solid          use solid tiles\n");
X  fprintf(stderr, "  -gw <n>         use gutter width of <n> pixels\n");
X  fprintf(stderr, "  -bw <n>         use border width of <n> pixels\n");
X  fprintf(stderr, "  -fg <c>         use <c> as forground color\n");
X  fprintf(stderr, "  -bg <c>         use <c> as background color\n");
X  fprintf(stderr, "  -bd <c>         use <c> as border color\n");
X  fprintf(stderr, "  -c0 <c>         use <c> as board color 0\n");
X  fprintf(stderr, "  -c1 <c>         use <c> as board color 1\n");
X  fprintf(stderr, "  -c2 <c>         use <c> as board color 2\n");
X  fprintf(stderr, "  -c3 <c>         use <c> as board color 3\n");
X  fprintf(stderr, "  -fn <f>         use font <f> for drawing text\n");
X
X  fprintf(stderr, "\nSee the man page for more info.\n\n");
X
X  exit(1);
X}
X
X
Xvoid MainLoop()
X{
X  XEvent xev;
X  void (*handler)();
X
X  while (1)
X  {
X    XNextEvent(dpy, &xev);
X    handler = GetEventHandler(&xev);
X    if (handler != NULL) handler(&xev);
X  }
X}
X
X
Xvoid drawBoard()
X{
X  int r, c;
X
X  /* redraw the tiles */
X  for (c=0; c<BoardSize; c++)
X    for (r=0; r<BoardSize; r++)
X      drawTile(r, c);
X  
X  /* redraw controller */
X  drawController();
X}
X
X
Xvoid drawHelp()
X{
X  /*
X   * mosaic quick help
X   * 
X   * q  quit
X   * s  toggle high scores window visibility
X   * h  toggle help window visibility
X   * n  new game (only enabled when current game is completed)
X   * a  automatic -- randomly place any remaining tiles
X   * 
X   * try `man mosaic' for further info
X   * press `h' to hide this window
X   */
X
X  int   fontsize;
X  int   x, y;
X  int   len;
X  char *txt;
X  
X  fontsize = font->ascent + font->descent;
X
X  x   = 10;
X  y   = font->ascent + gwidth;
X
X  y  += fontsize/2;
X  txt = "mosaic quick help";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X  y += fontsize/2;
X  y += fontsize;
X
X  txt = "q";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X
X  txt = "quit";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
X  y += fontsize;
X
X  txt = "s";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X  
X  txt = "toggle high scores window";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
X  y += fontsize;
X
X  txt = "h";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X
X  txt = "toggle help window";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
X  y += fontsize;
X
X  txt = "n";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X
X  txt = "new game";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
X  y += fontsize;
X
X  txt = "a";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X
X  txt = "automatic";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x+2*font->max_bounds.width, y, txt, len);
X  y += fontsize;
X
X  y += fontsize/2;
X  txt = "try `man mosaic' for further info";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X  y += fontsize;
X
X  txt = "(press `h' to hide this window)";
X  len = strlen(txt);
X  XDrawString(dpy, helpw, gc, x, y, txt, len);
X  y += fontsize;
X  y += fontsize/2;
X}
X
X
Xvoid drawTile(r, c)
X     int r, c;			/* tile position */
X{
X  int x, y;
X
X  x = c * TileSize + gwidth;
X  y = r * TileSize + gwidth;
X  
X  XCopyArea(dpy, tilep[tile[r*BoardSize+c]], boardw, gc,
X	    0, 0, TileSize, TileSize, x, y);
X}
X
X
Xvoid drawController()
X{
X  int x, y;
X  
X  x = ccol * TileSize + gwidth;
X  y = crow * TileSize + gwidth;
X  
X  XDrawRectangle(dpy, boardw, gc, x, y,
X		 TileSize*2-1, TileSize*2-1);
X  XDrawRectangle(dpy, boardw, gc, x+1, y+1,
X		 TileSize*2-3, TileSize*2-3);
X}
X
X
Xvoid drawNext()
X{
X  int p;
X  
X  p = (nextpiece < NPieces) ? piece[nextpiece] : 0;
X  
X  XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
X	    gwidth, gwidth);
X  p >>= 2;
X  XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
X	    gwidth+TileSize, gwidth);
X  p >>= 2;
X  XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
X	    gwidth, gwidth+TileSize);
X  p >>= 2;
X  XCopyArea(dpy, tilep[p&0x03], nextw, gc, 0, 0, TileSize, TileSize,
X	    gwidth+TileSize, gwidth+TileSize);
X}
X
X
Xvoid drawTitle()
X{
X  int   x, y;
X  int   len;
X  char *txt;
X
X  x   = (gwidth*2) + (bwidth) + (TileSize*BoardSize/2);
X  y   = (gwidth*4) + (bwidth*2) + (TileSize*BoardSize);
X  txt = AppName;
X
X  len = strlen(txt);
X  x  -= XTextWidth(font, txt, len) / 2;
X  y  += font->ascent;
X
X  XSetFont(dpy, gc, font->fid);
X  XDrawString(dpy, mainw, gc, x, y, txt, len);
X}
X
X
Xvoid drawScore()
X{
X  int   i, total;
X  int   top, left;
X  int   xtra, len;
X  int   x, y;
X  char *txt;
X  char  buf[16];
X
X  XSetFont(dpy, gc, font->fid);
X
X  left = (gwidth*5) + (bwidth*2) + (TileSize*BoardSize);
X  top  = (gwidth*4) + (TileSize*4);
X  xtra = (TileSize - (font->ascent + font->descent)) / 2;
X
X  txt = "to play";
X  len = strlen(txt);
X  x   = left + (swidth - XTextWidth(font, txt, len)) / 2;
X  y   = top + xtra + font->ascent;
X  XDrawString(dpy, mainw, gc, x, y, txt, len);
X  top += TileSize + gwidth;
X
X  for (i=0; i<3; i++)
X  {
X    XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
X    XCopyArea(dpy, tilep[i+1], mainw, gc, 0, 0,
X	      TileSize, TileSize, left, top);
X    sprintf(buf, "%d", remain[i]);
X    len = strlen(buf);
X    x   = left + swidth - gwidth - XTextWidth(font, buf, len);
X    y   = top + xtra + font->ascent;
X    XDrawString(dpy, mainw, gc, x, y, buf, len);
X    top += TileSize + gwidth;
X  }
X  top += TileSize + gwidth;
X
X  txt = "total";
X  len = strlen(txt);
X  x   = left + (swidth - XTextWidth(font, txt, len)) / 2;
X  y   = top + xtra + font->ascent;
X  XDrawString(dpy, mainw, gc, x, y, txt, len);
X  top += TileSize + gwidth;
X
X  total = 0;
X  for (i=0; i<3; i++)
X  {
X    total += tscore[i];
X    XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
X    XCopyArea(dpy, tilep[i+1], mainw, gc, 0, 0,
X	      TileSize, TileSize, left, top);
X    sprintf(buf, "%d", tscore[i]);
X    len = strlen(buf);
X    x   = left + swidth - gwidth - XTextWidth(font, buf, len);
X    y   = top + xtra + font->ascent;
X    XDrawString(dpy, mainw, gc, x, y, buf, len);
X    top += TileSize + gwidth;
X  }
X
X  XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
X  sprintf(buf, "%d", total);
X  len = strlen(buf);
X  x   = left + swidth - gwidth - XTextWidth(font, buf, len);
X  y   = top + xtra + font->ascent;
X  XDrawString(dpy, mainw, gc, x, y, buf, len);
X  top += TileSize + gwidth;
X  top += TileSize + gwidth;
X
X  txt = "piece";
X  len = strlen(txt);
X  x   = left + (swidth - XTextWidth(font, txt, len)) / 2;
X  y   = top + xtra + font->ascent;
X  XDrawString(dpy, mainw, gc, x, y, txt, len);
X  top += TileSize + gwidth;
X
X  total = 0;
X  for (i=0; i<3; i++)
X  {
X    total += pscore[i];
X    XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
X    XCopyArea(dpy, tilep[i+1], mainw, gc, 0, 0,
X	      TileSize, TileSize, left, top);
X    sprintf(buf, "%d", pscore[i]);
X    len = strlen(buf);
X    x   = left + swidth - gwidth - XTextWidth(font, buf, len);
X    y   = top + xtra + font->ascent;
X    XDrawString(dpy, mainw, gc, x, y, buf, len);
X    top += TileSize + gwidth;
X  }
X
X  XClearArea(dpy, mainw, left, top, swidth, TileSize, False);
X  sprintf(buf, "%d", total);
X  len = strlen(buf);
X  x   = left + swidth - gwidth - XTextWidth(font, buf, len);
X  y   = top + xtra + font->ascent;
X  XDrawString(dpy, mainw, gc, x, y, buf, len);
X  top += TileSize + gwidth;
X}
X
X
Xvoid drawHighScores()
X{
X  int   i;
X  int   fontsize;
X  int   x, y;
X  int   len;
X  char *txt;
X
X  fontsize = font->ascent + font->descent;
X
X  txt = HighScoreTitle;
X  len = strlen(txt);
X  x   = (hswidth - XTextWidth(font, txt, len)) / 2;
X  y   = fontsize/2 + font->ascent + gwidth;
X  XDrawString(dpy, scoresw, gc, x, y, txt, len);
X
X  y = fontsize*2 + gwidth;
X  for (i=0; i<NHighScores; i++)
X    if (highscore[i].score > 0)
X    {
X      XClearArea(dpy, scoresw, 0, y, hswidth, fontsize, False);
X      y += font->ascent;
X      
X      txt = highscore[i].uname;
X      len = strlen(txt);
X      XDrawString(dpy, scoresw, gc, gwidth*2, y, txt, len);
X      
X      sprintf(buf, "%d", highscore[i].score);
X      len = strlen(buf);
X      x   = hswidth - gwidth*2 - XTextWidth(font, buf, len);
X      XDrawString(dpy, scoresw, gc, x, y, buf, len);
X      
X      y += font->descent;
X    }
X}
X
X
Xvoid drawAll()
X{
X  drawBoard();
X  drawHelp();
X  drawNext();
X  drawTitle();
X  drawScore();
X  drawHighScores();
X}
X
X
Xstatic void doKey(xev)
X     XEvent *xev;
X{
X  if (XLookupString((XKeyEvent *) xev, buf, BufSize, NULL, NULL) > 0)
X    switch (buf[0])
X    {
X    case 'q':
X    case 'Q':
X      QuitGame();
X      break;
X
X    case 'n':
X    case 'N':
X    case '\n':
X    case '\r':
X      if (nextpiece == NPieces)
X      {
X	InitGame();
X	drawAll();
X      }
X      break;
X
X    case 's':
X    case 'S':
X      if (scoresvis)
X      {
X	XUnmapWindow(dpy, scoresw);
X	scoresvis = False;
X      }
X      else
X      {
X	XMapWindow(dpy, scoresw);
X	XRaiseWindow(dpy, scoresw);
X	scoresvis = True;
X      }
X      break;
X
X    case 'h':
X    case 'H':
X      if (helpvis)
X      {
X	XUnmapWindow(dpy, helpw);
X	helpvis = False;
X      }
X      else
X      {
X	XMapWindow(dpy, helpw);
X	helpvis = True;
X      }
X      break;
X
X    case 'a':
X    case 'A':
X      AutoPlay();
X      break;
X
X    case '\f':
X      drawAll();
X      break;
X    }
X}
X
X
Xstatic void doMotion(xev)
X     XEvent *xev;
X{
X  int    x, y;
X  Window dummyw;
X  int    row, col;
X  int    oldcr, oldcc;
X  int    redraw;
X  
X  /* motion event compression */
X  while (XCheckTypedEvent(dpy, MotionNotify, xev));
X
X  /* convert to boardw coordinates */
X  XTranslateCoordinates(dpy, xev->xmotion.window, boardw,
X			xev->xmotion.x, xev->xmotion.y,
X			&x, &y, &dummyw);
X
X  /* convert (x, y) to (row, col) */
X  row = (y - gwidth) / TileSize;
X  BoundVarVal(row, 0, (BoardSize-1));
X  col = (x - gwidth) / TileSize;
X  BoundVarVal(col, 0, (BoardSize-1));
X
X  /* check if redraw is necessary */
X  oldcr  = crow;
X  oldcc  = ccol;
X  redraw = False;
X  if (row < crow)
X  {
X    crow   = row;
X    redraw = True;
X  }
X  else if ((row - 1) > crow)
X  {
X    crow   = row - 1;
X    redraw = True;
X  }
X  if (col < ccol)
X  {
X    ccol   = col;
X    redraw = True;
X  }
X  else if ((col - 1) > ccol)
X  {
X    ccol   = col - 1;
X    redraw = True;
X  }
X
X  /* if necessary, redraw */
X  if (redraw)
X  {
X    /* redraw tiles */
X    drawTile(oldcr++, oldcc);
X    drawTile(oldcr, oldcc++);
X    drawTile(oldcr--, oldcc);
X    drawTile(oldcr, oldcc--);
X
X    /* draw controller at (crow, ccol) */
X    drawController();
X  }
X}
X
X
Xstatic void doBoardExpose(xev)
X     XEvent *xev;
X{
X  /* exposure event compression */
X  while (XCheckTypedWindowEvent(dpy, boardw, Expose, xev));
X
X  drawBoard();
X}
X
X
Xstatic void doHelpExpose(xev)
X     XEvent *xev;
X{
X  while (XCheckTypedWindowEvent(dpy, helpw, Expose, xev));
X
X  drawHelp();
X}
X
X
Xstatic void doNextExpose(xev)
X     XEvent *xev;
X{
X  /* exposure event compression */
X  while (XCheckTypedWindowEvent(dpy, nextw, Expose, xev));
X
X  drawNext();
X}
X
X
Xstatic void doMainExpose(xev)
X     XEvent *xev;
X{
X  /* exposure event compression */
X  while (XCheckTypedWindowEvent(dpy, mainw, Expose, xev));
X
X  drawTitle();
X  drawScore();
X}
X
X
Xstatic void doHighExpose(xev)
X     XEvent *xev;
X{
X  /* exposure event compression */
X  while (XCheckTypedWindowEvent(dpy, scoresw, Expose, xev));
X
X  drawHighScores();
X}
X
X
Xstatic void doButtonPress(xev)
X     XEvent *xev;
X{
X  if (helpvis)
X  {
X    XBell(dpy, 0);
X  }
X  else if ((nextpiece < NPieces) &&
X	   (DropPiece(crow, ccol, piece[nextpiece])))
X  {
X    nextpiece += 1;
X    drawNext();
X
X    if (nextpiece == NPieces)
X      CheckHighScore();
X  }
X}
X
X
Xstatic Pixel GetColor(name)
X     char *name;
X{
X  XColor xc;
X  
X  if (XParseColor(dpy, cmap, name, &xc) == 0)
X  {
X    sprintf(buf, "unable to parse color \"%s\"", name);
X    fatal(buf);
X  }
X
X  if (XAllocColor(dpy, cmap, &xc) == 0)
X    fatal("unable to alloc color");
X
X  return xc.pixel;
X}
X
X
Xstatic Window GetWindow(parent, x, y, w, h, b)
X     Window parent;
X     int    x, y;		/* position */
X     int    w, h;		/* dimensions */
X     int    b;			/* border width */
X{
X  return XCreateSimpleWindow(dpy, parent, x, y, w, h, b, brdr, back);
X}
X
X
Xstatic Pixmap MakePixmap(bits, w, h, fg, bg)
X     char *bits;
X     int   w, h;
X     Pixel fg, bg;
X{
X  return XCreatePixmapFromBitmapData(dpy, root, bits, w, h, fg, bg, dpth);
X}
X
X
Xstatic void SetCursor(w, idx)
X     Window w;
X     int    idx;
X{
X  Cursor curs;
X  XColor fg, bg;
X
X  curs = XCreateFontCursor(dpy, idx);
X
X  if (XParseColor(dpy, cmap, fgname, &fg) == 0)
X  {
X    sprintf(buf, "unable to parse color \"%s\"", fgname);
X    fatal(buf);
X  }
X  if (XParseColor(dpy, cmap, bgname, &bg) == 0)
X  {
X    sprintf(buf, "unable to parse color \"%s\"", bgname);
X    fatal(buf);
X  }
X
X  XRecolorCursor(dpy, curs, &fg, &bg);
X  XDefineCursor(dpy, w, curs);
X}
X
X
Xstatic void TopWindowStuff(w, name)
X     Window w;
X     char  *name;
X{
X  XWindowAttributes xwa;
X  XSizeHints       *xsh;
X
X  XGetWindowAttributes(dpy, w, &xwa);
X  
X  xsh = XAllocSizeHints();
X  xsh->width       = xwa.width;
X  xsh->height      = xwa.height;
X  xsh->min_width   = xwa.width;
X  xsh->min_height  = xwa.height;
X  xsh->max_width   = xwa.width;
X  xsh->max_height  = xwa.height;
X  xsh->base_width  = xwa.width;
X  xsh->base_height = xwa.height;
X  xsh->flags       = (PSize|PMinSize|PMaxSize|PBaseSize);
X
X  XSetWMNormalHints(dpy, w, xsh);
X  XStoreName(dpy, w, name);
X  XSetIconName(dpy, w, name);
X
X  XFree((char *) xsh);
X}
X
X
Xstatic void AddEventHandler(w, type, proc)
X     Window w;
X     int    type;
X     void (*proc)();
X{
X  if (XSaveContext(dpy, w,
X		   (XContext) type,
X		   (caddr_t) proc) != 0)
X    fatal("unable to XSaveContext");
X}
X
X
Xstatic void (*GetEventHandler(xev))()
X     XEvent *xev;
X{
X  void (*rslt)();
X  
X  if (XFindContext(dpy, xev->xany.window,
X		   (XContext) xev->xany.type,
X		   (caddr_t *) &rslt) != 0)
X    rslt = NULL;
X
X  return rslt;
X}
SHAR_EOF
$TOUCH -am 0130190491 x11.c &&
chmod 0444 x11.c ||
echo "restore of x11.c failed"
set `wc -c x11.c`;Wc_c=$1
if test "$Wc_c" != "28139"; then
	echo original size 28139, current size $Wc_c
fi
fi
# ============= x11.h ==============
if test X"$1" != X"-c" -a -f 'x11.h'; then
	echo "File already exists: skipping 'x11.h'"
else
echo "x - extracting x11.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > x11.h &&
X/*
X * x11.h
X * kirk johnson
X * october 1990
X */
X
X#ifndef _X11_H_
X#define _X11_H_
X
X#define TileSize   (20)
X#define MainCurs   (XC_dot)
X#define BoardCurs  (XC_crosshair)
X
X#define HighScoreTitle    "mosaic high scores"
X
X#define MainWindowName    "mosaic"
X#define ScoresWindowName  "mosaic scores"
X
X#define DfltGutterWidth  (2)
X#define DfltBorderWidth  (1)
X#define DfltForeName     "white"
X#define DfltBackName     "black"
X#define DfltBrdrName     "white"
X#define DfltC0Name       "white"
X#define DfltC1Name       "#c44"
X#define DfltC2Name       "#4c4"
X#define DfltC3Name       "#44c"
X#define DfltFontName     "-*-times-bold-r-*-*-*-180-*-*-*-*-*-*"
X
Xstatic char solidbits[] =	/* solid fill */
X{
X  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
X  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
X  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
X  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
X  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
X};
X
Xstatic char zerobits[] =	/* one small dot */
X{
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X};
X
Xstatic char onebits[] =		/* diagonal hashing */
X{
X  0x88, 0x88, 0x08, 0x44, 0x44, 0x04, 0x22, 0x22, 0x02, 0x11, 0x11, 0x01,
X  0x88, 0x88, 0x08, 0x44, 0x44, 0x04, 0x22, 0x22, 0x02, 0x11, 0x11, 0x01,
X  0x88, 0x88, 0x08, 0x44, 0x44, 0x04, 0x22, 0x22, 0x02, 0x11, 0x11, 0x01,
X  0x88, 0x88, 0x08, 0x44, 0x44, 0x04, 0x22, 0x22, 0x02, 0x11, 0x11, 0x01,
X  0x88, 0x88, 0x08, 0x44, 0x44, 0x04, 0x22, 0x22, 0x02, 0x11, 0x11, 0x01,
X};
X
Xstatic char twobits[] =		/* criss-cross */
X{
X  0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0xc4, 0x11, 0x07, 0x04, 0x10, 0x00,
X  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x8e, 0x38, 0x02,
X  0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00,
X  0xc4, 0x11, 0x07, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X  0x80, 0x00, 0x02, 0x8e, 0x3c, 0x02, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00,
X};
X
Xstatic char threebits[] =	/* bricks */
X{
X  0x04, 0x10, 0x00, 0x04, 0x10, 0x00, 0xff, 0xff, 0x0f, 0x80, 0x00, 0x02,
X  0x80, 0x00, 0x02, 0x80, 0x00, 0x02, 0x80, 0x00, 0x02, 0xff, 0xff, 0x0f,
X  0x04, 0x10, 0x00, 0x04, 0x10, 0x00, 0x04, 0x10, 0x00, 0x04, 0x10, 0x00,
X  0xff, 0xff, 0x0f, 0x80, 0x00, 0x02, 0x80, 0x00, 0x02, 0x80, 0x00, 0x02,
X  0x80, 0x00, 0x02, 0xff, 0xff, 0x0f, 0x04, 0x10, 0x00, 0x04, 0x10, 0x00,
X};
X
X#endif /* _X11_H_ */
SHAR_EOF
$TOUCH -am 0130190491 x11.h &&
chmod 0444 x11.h ||
echo "restore of x11.h failed"
set `wc -c x11.h`;Wc_c=$1
if test "$Wc_c" != "2766"; then
	echo original size 2766, current size $Wc_c
fi
fi
# ============= mosaic.man ==============
if test X"$1" != X"-c" -a -f 'mosaic.man'; then
	echo "File already exists: skipping 'mosaic.man'"
else
echo "x - extracting mosaic.man (Text)"
sed 's/^X//' << 'SHAR_EOF' > mosaic.man &&
X.TH mosaic 6 "22 January 1991"
X.SH NAME
Xmosaic
X.SH SYNOPSIS
Xmosaic [-options ...] 
X.SH DESCRIPTION
X.I Mosaic
Xis a simple adaption to X of the PC/MS-DOS game of the same name. 
X.sp
X.I Mosaic
Xis played with a set of 81 two-by-two tiles on a 24-by-24 playing
Xarea. The objective of the game is to place your tiles such that
Xsquares of the same pattern (color) are connected as much as possible. 
X.sp
XFor the purposes of scoring, similarly patterned squares are connected
Xonly if they share a side; touching diagonally on a corner doesn't
Xcount. 
X.sp
XEach of the 81 tiles is composed of four patterned squares. No two
Xtiles are the same, and each comes up once a game, in random order. 
X.SH HOW TO PLAY
XWhen playing
X.I mosaic,
Xthe next tile you have to play is shown in a two-by-two window in the
Xupper right corner of the
X.I mosaic
Xwindow. By moving the mouse pointer in the playing area window, you
Xcontrol where that tile will be placed, as indicated by the outline
Xwhich tracks the mouse pointer. To place the piece, press any mouse
Xbutton. 
X.sp
XWhile playing, the following key commands are available:
X.TP 4
X.B q
XQuit
X.I mosaic
X.TP 4
X.B s
XShow (or hide, if it's already visible) the high scores window
X.TP 4
X.B h
XHelp - show (or hide, if it's already visible) the help window. When
Xthe help window is visible, no pieces may be placed.
X.TP 4
X.B n
XNew game (only enabled when the current game is completed)
X.TP 4
X.B a
XAutomatic - randomly place any remaining tiles
X.SH SCORING
XAfter you place each tile,
X.I mosaic
Xidentifies all the connected regions of similarly patterned squares. 
XEach region then scores according to the square of the number of
Xsquares in the region. 
X.sp
X.I Mosaic
Xdisplays the total score, the total score broken down by pattern, and
Xthe amount those scores were improved by the most recently played
Xpiece. 
X.SH OPTIONS
X.TP 8
X.B \-help
XPrints a brief help message. 
X.TP 8
X.B \-display \fIdisplay\fP
XSpecifies the name of the X server to contact. 
X.TP 8
X.B \-expert
XBy default,
X.I mosaic
Xshows a "quick help" window upon startup. When this flag is used, the
X"quick help" window is not shown initially.
X.TP 8
X.B \-color
XCauses
X.I mosaic
Xto run in color mode (the default, except when using StaticGray and
XGrayScale visuals).
X.TP 8
X.B \-mono
XCauses
X.I mosaic
Xto run in monochrome mode. When in monochrome mode, only the
Xforeground (\-fg) and background (\-bg) colors are used (the default
Xwhen using StaticGray and GrayScale visuals).
X.TP 8
X.B \-patterns
XCauses
X.I mosaic
Xto use patterned tiles (the default).
X.TP 8
X.B \-solid
XCauses
X.I
Xmosaic
Xto use unpatterned (solid color) tiles. Probably not a good idea if
Xyou're running in monochrome mode.
X.TP 8
X.B \-gw \fInumber\fP
XSpecifies the gutter width (in pixels).
X.TP 8
X.B \-bw \fInumber\fP
XSpecifies the border width (in pixels);
X.TP 8
X.B \-fg \fIcolor\fP
XSpecifies the foreground color. 
X.TP 8
X.B \-bg \fIcolor\fP
XSpecifies the background color.
X.TP 8
X.B \-bd \fIcolor\fP
XSpecifies the border color.
X.TP 8
X.B \-c0 \fIcolor\fP
X.TP 8
X.B \-c1 \fIcolor\fP
X.TP 8
X.B \-c2 \fIcolor\fP
X.TP 8
X.B \-c3 \fIcolor\fP
XSpecifies the colors used to draw the background and tiles in the
Xplaying area.
X.TP 8
X.B \-fn \fIfont\fP
XSpecifies the font used for displaying text.
X.SH X DEFAULTS
X.TP 8
X.B Mono (type: boolean)
XSpecifies that
X.I mosaic
Xshould run in monochrome mode. The default is False.
X.TP 8
X.B Expert (type: boolean)
XWhen true, specifies that the "quick help" window should not be shown
Xupon startup. The default is False.
X.TP 8
X.B Solid (type: boolean)
XSpecifies that
X.I mosaic
Xshould use unpatterned (solid color) tiles. The default is False.
X.TP 8
X.B GutterWidth (type: number)
XSpecifies the gutter width (in pixels).
X.TP 8
X.B BorderWidth (type: number)
XSpecifies the border width (in pixels).
X.TP 8
X.B Foreground (type: color)
XSpecifies the foreground color. The default is \fIwhite\fP.
X.TP 8
X.B Background (type: color)
XSpecifies the background color. The default is \fIblack\fP.
X.TP 8
X.B BorderColor (type: color)
XSpecifies the border color. The default is \fIwhite\fP.
X.TP 8
X.B Color0 (type: color)
XSpecifies tile color zero. The default is \fIwhite\fP.
X.TP 8
X.B Color1 (type: color)
XSpecifies tile color one. The default is \fI#c44\fP.
X.TP 8
X.B Color2 (type: color)
XSpecifies tile color two. The default is \fI#4c4\fP.
X.TP 8
X.B Color3 (type: color)
XSpecifies tile color three. The default is \fI#44c\fP.
X.TP 8
X.B Font (type: color)
XSpecifes the font used for displaying text. The default is
X\fI-*-times-bold-r-*-*-*-180-*-*-*-*-*-*\fP.
X.SH AUTHOR
X.I Mosaic
Xwas written by Kirk Johnson <tuna@athena.mit.edu>. It is based on
XJoshua Klayman's PC/MS-DOS shareware game of the same name. This
Xversion is a complete rewrite encompasing only the basic
Xfunctionality of the original.
X.sp
XBug reports and suggestions are welcome.
SHAR_EOF
$TOUCH -am 0130190491 mosaic.man &&
chmod 0444 mosaic.man ||
echo "restore of mosaic.man failed"
set `wc -c mosaic.man`;Wc_c=$1
if test "$Wc_c" != "4792"; then
	echo original size 4792, current size $Wc_c
fi
fi
# ============= mosaic.scores ==============
if test X"$1" != X"-c" -a -f 'mosaic.scores'; then
	echo "File already exists: skipping 'mosaic.scores'"
else
echo "x - extracting mosaic.scores (Text)"
sed 's/^X//' << 'SHAR_EOF' > mosaic.scores &&
X. -1
X. -1
X. -1
X. -1
X. -1
X. -1
X. -1
X. -1
X. -1
X. -1
SHAR_EOF
$TOUCH -am 0130190491 mosaic.scores &&
chmod 0777 mosaic.scores ||
echo "restore of mosaic.scores failed"
set `wc -c mosaic.scores`;Wc_c=$1
if test "$Wc_c" != "50"; then
	echo original size 50, current size $Wc_c
fi
fi
exit 0
---------------- cut here


--
Dan Heller
------------------------------------------------
O'Reilly && Associates 		      Zyrcom Inc
Senior Writer			       President
argv@ora.com			argv@zipcode.com