Path: utzoo!attcan!uunet!tektronix!tekgen!tekred!games From: games@tekred.TEK.COM Newsgroups: comp.sources.games Subject: v05i064: mazewar-V - multiuser mazewar for System V Message-ID: <3038@tekred.TEK.COM> Date: 14 Sep 88 20:32:04 GMT Sender: billr@tekred.TEK.COM Lines: 788 Approved: billr@saab.CNA.TEK.COM Submitted by: Hans Korneder 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 '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 X#include 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= 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; playp_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 X#include 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; y0 ) 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