[comp.sources.games] v05i064: mazewar-V - multiuser mazewar for System V

games@tekred.TEK.COM (09/15/88)

Submitted by: Hans Korneder <uunet!altger!korn>
Comp.sources.games: Volume 5, Issue 64
Archive-name: mazewar-V

from the author:
[[Here goes a small game, which runs under Unix-III, Unix-V.{1,2,3}
and different flavours of Xenix.  The special thing about is: it uses
named pipes as a communication mechanism between the processes.
Thus it's a "realtime" interactive multiuser-game without sockets!]]

#! /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 shell archive."
# Contents:  README Makefile globals.h daemon.c maze.c user.c
# Wrapped by billr@saab on Wed Sep 14 13:29:49 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1256 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X/*
X * This file is part of "mazewar", an interactive
X * multiuser action game for non-BSD-Unix-systems.
X * Copyright (C) 1988 Hans Korneder      korn@altger.uucp
X * Permission is granted to the public
X * to copy all parts of the source, as long as no money
X * is made out of it, and the copyrightmessage is not removed.
X */
X
XOnce upon a time, there was a quite nice game on the net;
XIt was in interactive fullscreen multiuser action game.
XIt just had one small drawback: It used 'sockets',
Xa mechanism not available under my Unix V.
X
XTaking the idea, I rewrote a similar game, using
Xnamed pipes as an interprocess communication feature.
XThat game was successfully ported to Unix-III, Unix-V.{2,3},
Xand even several Xenixes.
X
XTo install:
X- compile the programs (according to the Makefile),
X- start up the serverdaemon-process in the background (this
X  process needs root-privileges; it has to be started only once;
X  best place is in some /etc/rc-script),
X- start the user-processes and have fun! (instructions
X  are displayed on the screen).
X- send money to me  :-)
X- send error-reports to /dev/null  :-)
X- send improvements to me !
X
X
XHope, you have fun with it!
X
XHans Korneder,      korn@altger.uucp
XWaldschulstr. 69
X8000 Muenchen 82
XFed. Rep. of Germany
END_OF_FILE
if test 1256 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(445 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XSHELL=/bin/sh
XCFLAGS=-O
XSRCES= user.c daemon.c maze.c
XINCLS= globals.h
XOBJS = $(SRCES:.c=.o)
Xall:	mazewar mazedaemon
Xmazewar:	user.o maze.o
X	cc user.o maze.o -lcurses -ltermcap -o mazewar
Xmazedaemon:	daemon.o maze.o
X	cc daemon.o maze.o -o mazedaemon
X$(OBJS):	globals.h
Xtape:;	tar cv README Makefile $(INCLS) $(SRCES)
Xclean:;	rm -f a.out core $(OBJS)
Xlove:;	@echo "my place or yours?"
Xshar:;	shar README Makefile $(INCLS) $(SRCES) > mazewar.shar
END_OF_FILE
if test 445 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'globals.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'globals.h'\"
else
echo shar: Extracting \"'globals.h'\" \(1333 characters\)
sed "s/^X//" >'globals.h' <<'END_OF_FILE'
X/*
X * This file is part of "mazewar", an interactive
X * multiuser action game for non-BSD-Unix-systems.
X * Copyright (C) 1988 Hans Korneder      korn@altger.uucp
X * Permission is granted to the public
X * to copy all parts of the source, as long as no money
X * is made out of it, and the copyrightmessage is not removed.
X */
X
X#define MAZE_DAEMON	"/usr/local/lib/mw_daemon_pipe"
X#define MAZE_PIPE   "/tmp/mw_user_XXXXXX"
X#define MAZE_SCORES "/usr/local/lib/mw_score_tbl"
X
X/* message-typen */
X#define MESSAGES 12345
X#define ANMELD   MESSAGES+0 /* new player comes in */
X#define SP_ANZ   MESSAGES+4 /* show player status */
X#define BEWEGUNG MESSAGES+5 /* player moves */
X#define BILD_NEU MESSAGES+7 /* screen refresh */
X#define EXIT     127
X
Xstruct anmeldung /* from the keyboard-client to the server */
X	{
X	int  an_magic;
X	int  an_pid;
X	int  an_uid;
X	char an_pipe[32];
X	} ;
X
Xstruct sp_anzeige /* fromm the server to the screen client */
X	{
X	int  sp_magic;
X	int  sp_pid;
X	int  sp_lfd_nr;
X	long sp_score;
X	int  sp_x_pos;
X	int  sp_y_pos;
X	char sp_name[9];
X	char sp_richtg;
X	char sp_flag; /* 1=in the game, 2=visible */
X	} ;
X
Xstruct bewegung /* from the keyboard client to the server */
X	{
X	int  be_magic;
X	int  be_pid;
X	int  be_code; /* also uid ! */
X	} ;
X
X#define MAZE_ROWS 19
X#define MAZE_COLS 40
Xextern char maze[MAZE_ROWS][MAZE_COLS];
END_OF_FILE
if test 1333 -ne `wc -c <'globals.h'`; then
    echo shar: \"'globals.h'\" unpacked with wrong size!
fi
# end of 'globals.h'
fi
if test -f 'daemon.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'daemon.c'\"
else
echo shar: Extracting \"'daemon.c'\" \(7906 characters\)
sed "s/^X//" >'daemon.c' <<'END_OF_FILE'
X/*
X * This file is part of "mazewar", an interactive
X * multiuser action game for non-BSD-Unix-systems.
X * Copyright (C) 1988 Hans Korneder      korn@altger.uucp
X * Permission is granted to the public
X * to copy all parts of the source, as long as no money
X * is made out of it, and the copyrightmessage is not removed.
X */
X
X#include <signal.h>
X#include <pwd.h>
X#include "globals.h"
X#define N_PLAYERS 10
X
Xstruct player
X	{
X	int  p_pid;
X	int  p_fd;
X	int  p_uid;
X	int  p_x_pos;
X	int  p_y_pos;
X	char p_name[9];
X	char p_richtg;
X	long p_score;
X	char p_pipe[32];
X	int  last_x[N_PLAYERS];
X	int  last_y[N_PLAYERS];
X	int  last_r[N_PLAYERS];
X	long last_s[N_PLAYERS];
X	} players[N_PLAYERS];
X
Xint delta_x[4] = { 1,0,-1,0 };
Xint delta_y[4] = { 0,-1,0,1 };
X
Xint player;
Xint user_pipe_fd, score_fd;
X
Xcatch(s)
Xint s;
X	{
X	signal(s,catch);
X	}
X
Xget_user_info(uid)
Xint uid;
X	{
X	extern struct passwd *getpwuid();
X	struct passwd *pwd;
X	pwd = getpwuid(uid);
X	if ( pwd ) strcpy(players[player].p_name,pwd->pw_name);
X	else sprintf(players[player].p_name,"*%06d*",uid);
X	if ( score_fd >= 0 )
X		{
X		lseek(score_fd,((long)uid)*sizeof(long),0);
X		read(score_fd,&(players[player].p_score),sizeof(long));
X		}
X	else players[player].p_score = 0L;
X	}
X
Xmain()
X	{
X	extern long time();
X	setpgrp();
X	catch(SIGALRM);
X	catch(SIGPIPE);
X	nice(-10); nice(-10); nice(-10); nice(-10);
X	srand((unsigned)time((long *)0));
X	umask(0);
X	score_fd = open(MAZE_SCORES,2);
X	for(;;)
X		{
X		unlink(MAZE_DAEMON);
X		mknod(MAZE_DAEMON,010622,0);
X		user_pipe_fd = open(MAZE_DAEMON,0);
X		if ( user_pipe_fd < 0 ) exit(1);
X		for(player=0; player<N_PLAYERS; player++)
X			players[player].p_pid = 0;
X		while(process_mesg());
X		close(user_pipe_fd);
X		sleep(2);
X		}
X	}
X
Xreposition_player(p)
Xint p;
X	{
X	extern int rand();
X	int y,x;
X	do	{
X		x = rand() % MAZE_COLS;
X		y = rand() % MAZE_ROWS;
X		} while ( maze[y][x] != ' ' );
X	players[p].p_x_pos = x;
X	players[p].p_y_pos = y;
X	players[p].p_richtg = rand()%4;
X	}
X
Xint process_mesg()
X	{
X	struct bewegung bew;
X	if ( read(user_pipe_fd,&bew,sizeof(bew))<=0 ) return 0;
X	switch ( bew.be_magic )
X		{
X		case ANMELD:
X			{
X			int p;
X			char answer_pipe[32];
X			read(user_pipe_fd,answer_pipe,sizeof(answer_pipe));
X			for(player=0; player<N_PLAYERS; player++)
X				if ( ! players[player].p_pid ) break;
X			if ( player==N_PLAYERS ) break;
X			strcpy(players[player].p_pipe,answer_pipe);
X			players[player].p_fd = open(players[player].p_pipe,1);
X			if ( players[player].p_fd<0 ) break;
X			players[player].p_pid = bew.be_pid;
X			players[player].p_uid = bew.be_code;
X			get_user_info(bew.be_code);
X			reposition_player(player);
X			for(p=0; p<N_PLAYERS; p++)
X				players[player].last_x[p] = -1,
X				players[player].last_s[p] = -1000000000; 
X			determine_visibility();
X			break;
X			}
X		case BEWEGUNG:
X			for(player=0; player<N_PLAYERS; player++)
X				if ( players[player].p_pid==bew.be_pid ) break;
X			if ( player==N_PLAYERS ) break;
X			do_cmd(bew.be_code);
X			determine_visibility();
X			break;
X		}
X	return 1;
X	}
X
Xsend_player_info(p1,p2,x,y,sicht) /* send info 'bout p1 to p2 */
Xint p1,p2,x,y,sicht;
X	{
X	struct sp_anzeige spa;
X	spa.sp_magic  = SP_ANZ;
X	spa.sp_pid    = players[p1].p_pid;
X	spa.sp_lfd_nr = p1;
X	spa.sp_flag   = sicht|1;
X	spa.sp_score  = players[p1].p_score;
X	spa.sp_x_pos  = x;
X	spa.sp_y_pos  = y;
X	spa.sp_richtg = players[p1].p_richtg;
X	strcpy(spa.sp_name,players[p1].p_name);
X	tell(p2,spa);
X	}
X
Xdo_cmd(cmd)
Xint cmd;
X	{
X	int p;
X	switch ( cmd )
X		{
X		case EXIT: /* leave game */
X			log_out(player);
X			break;
X		case 'S': /* shoot */
X			{
X			int new_x, new_y, p;
X			players[player].p_score -= 1; /* one shot costs 1 pt */
X			new_x=players[player].p_x_pos;
X			new_y=players[player].p_y_pos;
X			for(;;)
X				{
X				new_x += delta_x[players[player].p_richtg];
X				new_y += delta_y[players[player].p_richtg];
X				if ( maze[new_y][new_x] != ' ' ) break;
X				for(p=0; p<N_PLAYERS; p++)
X					if( players[p].p_pid &&
X						player!=p &&
X						players[p].p_x_pos==new_x &&
X						players[p].p_y_pos==new_y )
X							{
X							players[p].p_score -= 10;
X							reposition_player(p);
X							players[player].p_score += 10;
X							}
X				}
X			break;
X			}
X		case 'A': /* turn right */
X			players[player].p_richtg = (players[player].p_richtg+1)%4;
X			break;
X		case 'D': /* turn left */
X			players[player].p_richtg = (players[player].p_richtg+3)%4;
X			break;
X		case 'X': /* turn back */
X			players[player].p_richtg = (players[player].p_richtg+2)%4;
X			break;
X		case 'R': /* reposition */
X			players[player].p_score -= 5; /* one repos costs 5 pts */
X			reposition_player(player);
X			break;
X		case 'W': /* walk */
X			{
X			int new_x, new_y;
X			new_x = players[player].p_x_pos +
X				delta_x[players[player].p_richtg];
X			new_y = players[player].p_y_pos +
X				delta_y[players[player].p_richtg];
X			if ( maze[new_y][new_x] == ' ' )
X				{
X				players[player].p_x_pos = new_x;
X				players[player].p_y_pos = new_y;
X				}
X			break;
X			}
X		case ' ': /* backwalk */
X			{
X			int new_x, new_y;
X			new_x = players[player].p_x_pos +
X				delta_x[(players[player].p_richtg+2)%4];
X			new_y = players[player].p_y_pos +
X				delta_y[(players[player].p_richtg+2)%4];
X			if ( maze[new_y][new_x] == ' ' )
X				{
X				players[player].p_x_pos = new_x;
X				players[player].p_y_pos = new_y;
X				}
X			break;
X			}
X		break;
X		}
X	}
X
Xlog_out(p)
Xint p;
X	{
X	int play;
X	/* recursion can occur, therefore use local structs ! */
X	struct sp_anzeige raus;
X	if ( score_fd >= 0 )
X		{
X		lseek(score_fd,((long)players[p].p_uid)*sizeof(long),0);
X		write(score_fd,&(players[player].p_score),sizeof(long));
X		}
X	raus.sp_magic  = SP_ANZ;
X	raus.sp_pid    = players[p].p_pid;
X	raus.sp_lfd_nr = p;
X	raus.sp_x_pos  = players[p].p_x_pos;
X	raus.sp_y_pos  = players[p].p_y_pos;
X	raus.sp_flag   = 0;
X	for(play=0; play<N_PLAYERS; play++)
X		tell(play,raus);
X	close (players[p].p_fd  );
X	unlink(players[p].p_pipe);
X	players[p].p_pid = 0;
X	}
X
Xtell(p,spa)
Xint p;
Xstruct sp_anzeige spa;
X	{
X	if ( players[p].p_pid )
X		{
X		int n_bytes;
X		alarm(3);
X		n_bytes = write(players[p].p_fd,&spa,sizeof(spa));
X		alarm(0);
X		if ( n_bytes<1 )
X			{
X			players[p].p_pid = 0; /* avoid endless recursion */
X			log_out(p); /* recursion */
X			}
X		}
X	}
X
Xdetermine_visibility()
X	{
X	register i,j; /* speedup */
X	for(i=0; i<N_PLAYERS; i++)
X	if ( players[i].p_pid )
X	for(j=0; j<N_PLAYERS; j++)
X	if ( players[j].p_pid )
X	{
X	int visibel;
X	register struct player *pi, *pj; /* speedup */
X	pi = players + i; pj = players + j;
X	visibel = (pi->p_x_pos == pj->p_x_pos)
X		||    (pi->p_y_pos == pj->p_y_pos) ;
X	if ( visibel )
X		{
X		/* i can view j. */
X		/* did he see him before 
X		at the same position ? */
X		if ( (pj->p_x_pos == pi->last_x[j]) &&
X			 (pj->p_y_pos == pi->last_y[j]) &&
X			 (pj->p_richtg== pi->last_r[j]) &&
X			 (pj->p_score == pi->last_s[j]) )
X			{ /* then: nothing to do. */ }
X		else /* he was somewhere else before. */
X			{
X			/* was he in the game at all ? */
X			if ( pi->last_x[j]>=0 )
X				/* did he just look in another direction? */
X				if ( (pj->p_x_pos == pi->last_x[j]) &&
X					 (pj->p_y_pos == pi->last_y[j]) )
X					{ /* nothing to erase then. */ }
X				else
X					/* his last position has to be erased
X					on the screen. */
X					send_player_info(j,i,pi->last_x[j],pi->last_y[j],0);
X			/* store new position and send it. */
X			pi->last_x[j] = pj->p_x_pos;
X			pi->last_y[j] = pj->p_y_pos;
X			pi->last_r[j] = pj->p_richtg;
X			pi->last_s[j] = pj->p_score;
X			send_player_info(j,i,pi->last_x[j],pi->last_y[j],2);
X			}
X		}
X	else
X		{
X		/* i cannot view j. did he not see him before? */
X		if ( pi->last_x[j]<0 )
X			/* if score changed, display though */
X			if ( pi->last_s[j] == pj->p_score )
X				{ /* nothing to do here */ }
X			else
X				{
X				send_player_info(j,i,pi->last_x[j],pi->last_y[j],0);
X				pi->last_s[j] = pj->p_score;
X				}
X		else /* he was visibel before. */
X			{
X			/* his last position on the screen has to be erased */
X			send_player_info(j,i,pi->last_x[j],pi->last_y[j],0);
X			pi->last_x[j] = -1;
X			}
X		}
X	}
X	}
X
X/* END */
END_OF_FILE
if test 7906 -ne `wc -c <'daemon.c'`; then
    echo shar: \"'daemon.c'\" unpacked with wrong size!
fi
# end of 'daemon.c'
fi
if test -f 'maze.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'maze.c'\"
else
echo shar: Extracting \"'maze.c'\" \(1450 characters\)
sed "s/^X//" >'maze.c' <<'END_OF_FILE'
X/*
X * This file is part of "mazewar", an interactive
X * multiuser action game for non-BSD-Unix-systems.
X * Copyright (C) 1988 Hans Korneder      korn@altger.uucp
X * Permission is granted to the public
X * to copy all parts of the source, as long as no money
X * is made out of it, and the copyrightmessage is not removed.
X */
X
X#include "globals.h"
X
Xchar maze[MAZE_ROWS][MAZE_COLS] = {
X/*        0123456789012345678901234567890123456789   */
X/*  0 */ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
X/*  1 */ "X X       X    X    X         X        X",
X/*  2 */ "X X X X X X XX X XX X XXXX XXXX XXXXXX X",
X/*  3 */ "X   X X X X X  X X  X   X   X   X      X",
X/*  4 */ "X X X X X X XX   XX   X   X   XXXXXX XXX",
X/*  4 */ "X X X   X    X X  X X X  XXX       X   X",
X/*  5 */ "X X XXX XXXXXX XXXX X XXXX XXXXXXX X X X",
X/*  6 */ "X X                              X X X X",
X/*  7 */ "X XXXX XXXXXXX X XXXXXXXXX XXXXXXX X X X",
X/*  8 */ "X      X       X     X        X  X X   X",
X/*  9 */ "X XX XXX XXXXX X XXX X XXXXXX X XX XXX X",
X/* 10 */ "X X      X   X X     X                 X",
X/* 11 */ "X X XX X X X X XXXXX XXXX XXXXXXXXXX XXX",
X/* 12 */ "X X X  X X X   X   X X        X        X",
X/* 13 */ "X X XX X X X X X X X X XXXXXX XXXXX XXXX",
X/* 14 */ "X      X   X X   X     X      X        X",
X/* 15 */ "XX XXXXX X X XXX XXXXXXX X XXXX X XXXX X",
X/* 16 */ "X        X   X           X      X      X",
X/* 17 */ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
X} ;
END_OF_FILE
if test 1450 -ne `wc -c <'maze.c'`; then
    echo shar: \"'maze.c'\" unpacked with wrong size!
fi
# end of 'maze.c'
fi
if test -f 'user.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'user.c'\"
else
echo shar: Extracting \"'user.c'\" \(4907 characters\)
sed "s/^X//" >'user.c' <<'END_OF_FILE'
X/*
X * This file is part of "mazewar", an interactive
X * multiuser action game for non-BSD-Unix-systems.
X * Copyright (C) 1988 Hans Korneder      korn@altger.uucp
X * Permission is granted to the public
X * to copy all parts of the source, as long as no money
X * is made out of it, and the copyrightmessage is not removed.
X */
X
X#include <signal.h>
X#include <curses.h>
X#include "globals.h"
X
Xchar *user_pipe_name;
Xint user_pipe_fd, daemon_pipe_fd;
Xint parent_pid, child_pid;
Xchar richtung[4] = { '>','^','<','v' };
X
Xcatch(s)
Xint s;
X	{
X	signal(s,catch);
X	}
X
Xfehler(text)
Xchar *text;
X	{
X	standout();
X	mvaddstr(23,0,text);
X	standend();
X	refresh();
X	sleep(4);
X	}
X
Xmain()
X	{
X	catch(SIGALRM);
X	catch(SIGPIPE);
X	parent_pid = getpid();
X	initscr(); noecho(); raw();
X	draw_maze();
X	if ( init_pipes() ) play_the_game();
X	clear(); refresh(); noraw(); echo(); endwin();
X	}
X
Xdraw_maze()
X	{
X	int x,y;
X	erase();
X	for(y=0; y<MAZE_ROWS; y++)
X		{
X		move(y,0);
X		for(x=0; x<MAZE_COLS; x++)
X			if ( maze[y][x] != ' ' ) addstr("[]");
X			else                     addstr("  ");
X		}
X	mvaddstr(19,0,"a = turn left");
X	mvaddstr(20,0,"d = turn right");
X	mvaddstr(21,0,"x = turn back");
X	mvaddstr(22,0,"s = shoot");
X	mvaddstr(23,0,"q = quit");
X	mvaddstr(19,20,"w = walk");
X	mvaddstr(20,20,"_ = walk back");
X	mvaddstr(21,20,"r = reposition");
X	refresh();
X	}
X
Xint init_pipes()
X	{
X	int n_bytes;
X	extern char *mktemp();
X	struct anmeldung anm;
X	umask(0);
X	user_pipe_name = mktemp(MAZE_PIPE);
X	if ( mknod(user_pipe_name,010600,0)<0 )
X		{
X		fehler("MAZE_PIPE cannot be created");
X		return 0;
X		}
X	user_pipe_fd = open(user_pipe_name,2);
X	if ( user_pipe_fd<0 )
X		{
X		fehler("MAZE_PIPE cannot be opened");
X		return 0;
X		}
X	alarm(3);
X	daemon_pipe_fd = open(MAZE_DAEMON,1);
X	alarm(0);
X	if ( daemon_pipe_fd<0 )
X		{
X		fehler("MAZE_DAEMON_PIPE cannot be opened");
X		return 0;
X		}
X
X	/* startup message to the daemon */
X	anm.an_magic = ANMELD;
X	anm.an_pid   = parent_pid;
X	anm.an_uid   = getuid();
X	strcpy(anm.an_pipe,user_pipe_name);
X	alarm(3);
X	n_bytes = write(daemon_pipe_fd,&anm,sizeof(anm));
X	alarm(0);
X	if ( n_bytes<0 )
X		{
X		fehler("startupmessage to the daemon could not be sent");
X		return 0;
X		}
X
X	return 1;
X	}
X
Xplay_the_game()
X	{
X	switch( child_pid=fork() )
X		{
X		case -1:
X			fehler("cannot fork");
X			break;
X		case 0: /* child */
X			child_proc();
X			break;
X		default: /* parent */
X			parent_proc();
X			break;
X		}
X	}
X
Xchild_proc()
X	{
X	struct sp_anzeige spa;
X	close(user_pipe_fd);
X	user_pipe_fd = open(user_pipe_name,0);
X	while ( read(user_pipe_fd,&spa,sizeof(spa))>0 )
X		switch ( spa.sp_magic )
X			{
X			case BILD_NEU:
X				clearok(stdscr);
X				refresh();
X				break;
X			case SP_ANZ:
X				if ( spa.sp_flag & 1 ) /* within the game */
X					mvprintw(19+spa.sp_lfd_nr%5,40+(spa.sp_lfd_nr/5)*20,
X					"%c: %-8.8s %6d", spa.sp_lfd_nr+'A', spa.sp_name,
X					spa.sp_score);
X				else /* Aus dem Spiel raus */
X					mvaddstr(19+spa.sp_lfd_nr%5,40+(spa.sp_lfd_nr/5)*20,
X					"                  ");
X				if ( spa.sp_flag & 2 ) /* visible */
X					{
X					move(spa.sp_y_pos,spa.sp_x_pos*2);
X					if ( spa.sp_pid==parent_pid )
X						addch(richtung[spa.sp_richtg]);
X					else
X						addch(spa.sp_lfd_nr + 'A');
X					addch(richtung[spa.sp_richtg]);
X					}
X				else
X					mvaddstr(spa.sp_y_pos,spa.sp_x_pos*2,"  ");
X				refresh();
X				break;
X			}
X	exit(0);
X	}
X
Xparent_proc()
X	{
X	long now;
X	int code, status;
X	struct bewegung bew;
X	struct sp_anzeige spa;
X	static long last_shot = 0;
X	extern long time();
X
X	bew.be_magic = BEWEGUNG;
X	bew.be_pid   = parent_pid;
X	spa.sp_magic = BILD_NEU;
X	do	switch( code=getch() )
X		{
X		case 'a': case 'A':
X			bew.be_code = 'A';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 'd': case 'D':
X			bew.be_code = 'D';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 'x': case 'X':
X			bew.be_code = 'X';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 'w': case 'W':
X			bew.be_code = 'W';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case ' ': case '_':
X			bew.be_code = ' ';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 's': case 'S':
X			/* allow for 1 shot per second */
X			now = time((long *)0);
X			if ( last_shot == now ) break;
X			last_shot = now;
X			bew.be_code = 'S';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 'r': case 'R':
X			bew.be_code = 'R';
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 'Q': case 'q': case 127: case 4: /* ^D */
X			code        = EXIT;
X			bew.be_code = EXIT;
X			if ( write(daemon_pipe_fd,&bew,sizeof(bew) )<0 ) code=EXIT;
X			break;
X		case 12: /* ^L */ case 022: /* ^R */
X			if ( write(user_pipe_fd  ,&spa,sizeof(spa) )<0 ) code=EXIT;
X			break;
X		}
X		while ( code!=EXIT );
X	close(user_pipe_fd);
X	while ( wait(&status) != child_pid ) ;
X	}
X
Xmsg(t)char*t;{write(2,t,strlen(t));}
X/* ENDE */
END_OF_FILE
if test 4907 -ne `wc -c <'user.c'`; then
    echo shar: \"'user.c'\" unpacked with wrong size!
fi
# end of 'user.c'
fi
echo shar: End of shell archive.
exit 0