[net.games.emp] Visual Empire for Old Empire 1 of 2

tsf@druxn.UUCP (FisherTS) (12/02/85)

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by tsf on Sun Dec  1 15:00:54 MST 1985
# Contents:  ./MAN/ ./_unix.O/ ./hdrs/ ./EHELP/ ./EHELP/_unix.O/ ./README
#	./Buglist ./Makefile ./MAN/ehelp.1 ./MAN/eupd.1 ./_unix.O/genlib.a
#	./hdrs/emp.h ./hdrs/ship.h ./EHELP/ehelp.c ./EHELP/Makefile
#	./EHELP/_unix.O/ehelp.o
 
echo x - ./README
sed 's/^@//' > "./README" <<'@//E*O*F ./README//'
	==[  Instructions for installing Old Empire playing aids  ]==

1) If you are on a 4.2BSD system, change emp.h to uncomment the
   #define BSD.  For SysV, nothing has to be changed.  Also, for
   4.2BSD systems, you might want to use the 4.2mkfile in GENLIB,
   TERMLIB, and UPDLIB instead of the Makefiles provided.

2) When any modifications have been made, do:
	make clobber 
	make all

There are five main programs that are made: 

ecre	- program to create your local sector database (newsect)
	  also can be used to relocate in case you have to move your
	  capital.

eupd	- program to extract info from Old Empire game output and update
	  your local sector database (empsect) and ship database (empship).

ehelp	- Old Empire "visual empire".  Screen oriented display of your
	  local databases (empsect & empship), and Old Empire command script
	  generator.  Script gets written into file called .yout.  I have
	  no idea why it was named .yout.

pworld	- program to print out the world from your empsect file.

rdship	- program to list the ships in your empship file.

In addition, there are several shell/awk programs in MISC that I have
found useful.  They also demonstrate alternate ways to change or look at
your local database.

3) This version is meant to be played with Version 1.1 and any more recent
   versions of Old Empire.

4) The file, Buglist contains all known bugs fixed and remaining in this
   version.

5) This package was incrementally thrown together as adversaries
   put pressure on the author's country.  There are lots of opportunities
   for improving the function and human factors of ehelp, and eupd contains
   one of the most bizarre uses of lex and yacc I've ever seen - but it
   works.  The whole idea behind this set of tools was to make the emp'ing
   more efficient than using grid paper and colored pencils, and using
   up your BTU and time allocation doing census, map, ship, and mov
   commands.  Generally, only the "unpredictable" commands are executed
   without a script (attack, assault, fly, board, spy).
   
6) Send all bug reports and wish list items to ihnp4!druxn!tsf.
@//E*O*F ./README//
chmod u=rw,g=r,o=r ./README
 
echo x - ./Buglist
sed 's/^@//' > "./Buglist" <<'@//E*O*F ./Buglist//'
		==[ All the bugs that fit, we print ]==

		Version 1.0 Visual Empire for Old Empire
			   December 1985

Things that generate incorrect scripts, core dumps, hung terminals,
cpu loops, inaccurate displays, are bugs.  Things that are inconvenient,
un-pretty, incomplete, are items for the wish list.  Please send all
bug reports and wish list items to ihnp4!druxn!tsf.
@//E*O*F ./Buglist//
chmod u=rw,g=r,o=r ./Buglist
 
echo x - ./Makefile
sed 's/^@//' > "./Makefile" <<'@//E*O*F ./Makefile//'
MAKE=make
LIBDIR=./_unix.O
GENLIB=$(LIBDIR)/genlib.a
TERMLIB=$(LIBDIR)/termlib.a
UPDLIB=$(LIBDIR)/updlib.a

all:	$(GENLIB) $(TERMLIB) $(UPDLIB) eupd ehelp ecre pworld rdship
	@echo All done!

$(GENLIB):	FRC
	@echo GENLIB:
	@cd GENLIB; $(MAKE)

genlib.a:	$(GENLIB)

$(TERMLIB):	FRC
	@echo TERMLIB:
	@cd TERMLIB; $(MAKE)

termlib.a:	$(TERMLIB)

$(UPDLIB):	FRC
	@echo UPDLIB:
	@cd UPDLIB; $(MAKE)

updlib.a:	$(UPDLIB)

eupd:		FRC
	@echo EUPD:
	@cd EUPD; $(MAKE)

ehelp:		FRC
	@echo EHELP:
	@cd EHELP; $(MAKE)

ecre:		FRC
	@echo ECRE:
	@cd ECRE; $(MAKE)

pworld:		FRC
	@echo "MISC (pworld):"
	@cd MISC; $(MAKE) pworld

rdship:		FRC
	@echo "MISC (rdship):"
	@cd MISC; $(MAKE) rdship

clean:
	@cd GENLIB; $(MAKE) clean
	@cd TERMLIB; $(MAKE) clean
	@cd UPDLIB; $(MAKE) clean
	@cd EUPD; $(MAKE) clean
	@cd EHELP; $(MAKE) clean
	@cd ECRE; $(MAKE) clean
	@cd MISC; $(MAKE) clean

clobber:
	@cd GENLIB; $(MAKE) clobber
	@cd TERMLIB; $(MAKE) clobber
	@cd UPDLIB; $(MAKE) clobber
	@cd EUPD; $(MAKE) clobber
	@cd EHELP; $(MAKE) clobber
	@cd ECRE; $(MAKE) clobber
	@cd MISC; $(MAKE) clobber

@.PRECIOUS:	$(GENLIB) $(TERMLIB) $(UPDLIB)

FRC:
@//E*O*F ./Makefile//
chmod u=rw,g=r,o=r ./Makefile
 
echo mkdir - ./MAN
mkdir ./MAN
chmod u=rwx,g=rx,o=rx ./MAN
 
echo x - ./MAN/ehelp.1
sed 's/^@//' > "./MAN/ehelp.1" <<'@//E*O*F ./MAN/ehelp.1//'
ehelp - an Old Empire playing aid			Version 1.0  12/85

There are three programs designed (hacked together) to reduce the
empire playing time, while maximizing the enjoyment of interacting
with the other players.  The program captures data from Old Empire
output (e.g. census, ship, radar, ...), and uses a screen oriented
user interface to display the accumulated knowledge of the world.
The user uses the display to create a empire command script which
can be executed with the "ex" command.  In this way, delivery routes
can be established, goods can be moved, ships can be navigated, etc.

The four programs are:   ecre, ehelp, and eupd.

They are used in the following sequence:

  COMMAND			WHAT TO DO WITH IT
1. ecre	[-x new_capx] [-y new_capy]
		Invoked without arguments, it creates an empty world
		in a file called, "newsect".
		Create a file "newsect".  Rename it "empsect" after
		optionally saving the old world.  Also create an empty
		file called "empship" ( >empship). 
		Invoked with arguments, this command can be used to change 
		the location of your capital.  In fact, if you don't use
		this program to reflect a new capital location, your view
		of the world will get all hosed up. If you designate 1,3
		as a new capital, use  ecre -x 1 -y 3 to create a "newsect"
		having the appropriate adjustments.

2. play empire, saving the output in a file 
	(e.g. empire Cname rep | tee outfile)
	Optionally use scripts generated in step 4.

3. eupd < outfile
		Update your view of the world.  This updates
		empsect and empship. I don't think eupd handles
		"route" command output very gracefully, so don't use "route".
		 Use "census" and ehelp instead.
   eupd -p
		Suppose your neighbor has taken over most of your western
		border while you were on a trip to New Jersey.  The updater
		isn't smart enough to read through the telegrams and find out
		what you no longer own.  This can be handled by issuing:

			eupd -p

		This purges the world of all sectors owned by you.  To get the
		sectors assigned to you again, simply do a cen # (the whole
		world) and run the output through the eupd command.  The
		sectors you no longer own will be missing in the census output,
		and therefore they will remain unowned on your map.  Of course,
		the best strategy of all is never take a trip to New Jersey.

4. ehelp	Enter the screen oriented display, and create the
		desired command scripts.  These scripts are written in a
		file called .yout .
		Now erase outfile, and go back to step 2.

Use ehelp like this:

While in ehelp, the cursor is either on the map or down in the lower left
corner waiting for command input.  Furthermore, ehelp is either set up for
a specified empire command or it's waiting for you to specify a command
(or possibly map coordinates).

When your prompt is ">" in the lower left corner, you haven't specified
a command yet.  In this mode, the following is legal:

Enter:
	x,y		change center coordinates
	map		display map
	cen		set up for census commands
	mov		set up for move commands
	del		set up for delivery commands
	des		set up for designate commands
	shi		set up for ship commands
	nav		set up for navigate commands
	>command	append the string following the ">" to .yout
	crtl-d		exit ehelp

When you set up any of the command modes (cen, des, etc.) your prompt
will change, and the information block in the upper right will change.

For commands like mov, del, des, you change the quantity, designation,
resource, threshold, etc. by entering the number or letter while the
cursor is in the lower left corner, next to the prompt.
For example, after entering des, the cursor will still be in the lower
left corner.  Note that the default designation in the information block
in the upper right is 'g'.  Type d to change the designation to a defense
plant, for example.

To leave the specified command mode, type '.' or ctrl-d when the cursor
is in the corner.

After entering the number or letter, the cursor will go up to the
map.  To bring the cursor back to the corner, hit the return key.
When the cursor is in the corner, put it on the map by hitting the
return key.

Once on the map, move around by using the 
		  w  e  r                 k
		   \ | /                  |
		  s - - d      or      h - - l
		   / | \                  |
		  z  x  c                 j

keys.  When positioned over a sector, hit the tab (ctrl-i) to see
what's in that sector.  If you're in ship or nav mode, hit 'I' and
'i' to see other useful info.

Nothing gets written to the script file (.yout) unless you're on the
map and you hit the space bar, or you use the ">command" feature
shown above.

Specific commands:

When the prompt is ">", type "map" to get a map drawn on the screen.
The display is centered around the coordinates chosen (default is 0,0).
It might look like this:
	 .  -  .  m 
	 f  h  m  ^?
	 .  *  f  f  d  ?
	 m  i  m  u  ?  ? 

Question marks indicate sectors you don't own.  Sometimes the designation
is shown just to the left of the '?'.  In the display above, the mountain
was detected by a map or spy command, and the fact that it's owned by
someone else was probably obtained from a spy command.  The other '?'s
were probably the result of a map command.

To get a census command appended to .yout, enter cen mode and postition
the cursor on the sector you want a census of.  Then hit the space bar.

To designate sectors, enter des mode and select a designation.
Position the cursor on the victim sector, and hit the space bar.
A "des" command will be appended to .yout.

To establish a delivery route, enter del mode.  Select resource
and threshold.  Note that the screen will be redrawn showing the 
existing routes for the selected resource.
When in del mode, position the cursor on the supplying
sector, then type a '+'.  Next, position the cursor on the adjacent
receiving sector, and hit the space bar.  A "del" command will be
appended to .yout, and the receiving sector is automatically marked
as the next supplying sector.  Move the cursor to the next receiving
sector, and hit the space bar again.  To indicate a new supplying
sector at any time, position the cursor, then type '+'.  Your route is
shown as you construct it on the map, but remember that no changes are
made to the empire world until you run the script.  In fact, your
local database isn't changed either.  It will change when you run the
output of the empire session (with appropriate census output) through eupd.

To move things around, enter mov mode.  Select resource and quantity.
Position cursor on the supplying sector, then type a '+'.  Move
the cursor to the next sector in the route to the destination and
type another '+'.  Continue in this way until the cursor is positioned
on the destination sector.  Instead of typing '+', hit the space bar.
A "mov" command will be appended to .yout.  The route will be indicated
with '@' characters.  To tear down the route completely or partially,
type a '-'.
Ships are navigated the same way, except you enter nav mode, and
select a ship number, group of ships (124/35/245), or all ships
in the starting sector (type a ',' instead of ship number).  Hit
the space bar to append a "nav" command to .yout .

To find out where all the ships are, enter ship mode.  You can limit
the operation to ships of only certain types by entering a string
next to the prompt.  For example, to limit operations to carriers
and battleships, type "cb".  To reinstate the full list again, type
"*".  To get a display of all the ships known to you, type "?".
Your ships will be to the right of the sector, and other country
ships will be positioned to the left.  Ships are shown as capital letters.
For example your harbor with a pt boat in it and someone else's battleship
just to the north would look like this:
	 .  .  .  . 
	 m B.  .  f
	 f  hP *  m
	 ^  f  m  u

All the ships in a particular sector "stack" up, and only the ship with the
highest number is shown.  If there were 30 ships in your harbor above, and
several other countries had parked ships just to the north, the display
would look the same so long as the battleship and pt boat had the highest
ship number in that sector.  Watch out for capital letters to the left
of your harbors...

There is a way to limit the other country display to just a particular 
country, perhaps an enemy of particular interest.  Before invoking
ehelp, set the shell variable FOES to the country number of interest.
e.g.  FOES=4
      export FOES
Then invoke ehelp.  The numbers next to the sectors are the ones-digits
of the owning country number (11 and 1 will look alike), and ship displays
will be limited to just your ships and ships owned by the country number
FOES was set to.

Note that you can change your database (empsect and empship) just by
faking empire output and running it through eupd.  For example, suppose
your ship hits a mine.  You could have a shell script named "mine" that
takes the x,y coordinate of the mined sector and produces a fake
census command output having zero values for everything except the shells.
One effect of this is to change the '.' on the map to a ':' when that
sector is displayed.  Hopefully you can avoid that sector when doing a "nav".
To get rid of the ':', fake a census command that has shells=0.
Another example is when ships sink (gasp!).  You can fake a ship
command output and set the efficiency to zero.  This way, the ship won't
be displayed.

You can also hose up your database pretty badly if you don't know what
you're doing with all these fake commands.

One last trick.  Suppose you want to set up delivery routes for ore, shells
and guns all in one shot without having to wait for the screen to redraw
at 1200 baud.  The trick is to change the resource with the mov command
instead of with the del command.  Enter del, and select o as the resource.
The screen redraws showing the ore delivery routes.  Get on the map and
set up your new ore routes.  Then hit a return.  That puts you back at
the prompt.  Instead of selecting another resource (which would cause the
map to be redrawn), leave the del mode by entering a '.' or ctrl-d.
Now enter mov mode.  Change the resource to s (shells).  Leave mov mode,
and re-enter del mode.  Without entering a resource, hit the return key
to get on the map.  Now set up your shell delivery routes.  Go on to do
the gun routes the same way.  Not pretty, but it works.

While you're still getting familiar with ehelp, be sure to check your
scripts.  Make sure they're what you intended.  Otherwise you could end
up doing something you didn't want to do.  Also, if you suspect that the
map isn't being drawn in the right place on the screen (bad termcap, flaky
terminal, noisy line, program bugs(gasp!)), redraw the screen before
creating another line of script.  Otherwise, the coordinates of the script
commands will be wrong.
@//E*O*F ./MAN/ehelp.1//
chmod u=rw,g=r,o=r ./MAN/ehelp.1
 
echo x - ./MAN/eupd.1
sed 's/^@//' > "./MAN/eupd.1" <<'@//E*O*F ./MAN/eupd.1//'
eupd - an Old Empire playing aid			Version 1.0  12/85

Eupd is used to extract information from Old Empire output and update
your local sector and ship databases (empsect and empship).  Version 1.0
eupd extracts information from the following command outputs:

census		map		ship		navigate	look
radar		deliver		spy		fly

For the navigate command, only the "ship #nn stopped at x,y" message
is extracted, and the coordinates of your ships is updated.  The mobility
is left unchanged.

For the look command, in addition to the land and ship information extracted,
a message is printed when a sub is detected.  The sub's presence is not
written into the empship file.  It is assumed that you'll want to go take
a closer "look" to get the sub's number and country info.

The output of delivery commands of the following form:
	del o #1 -
is parsed for the threshold information.  The delivery direction is
gotten from the cesus command.

For the spy command, all the normal info is parsed, but when the spy
is shot, no info is extracted.  When the spy is deported, the sector that
deported the spy is checked to see if you own it.  That is, your local
database is checked to see if you think you still own that sector.  If
your database indicates (falsely) that you still own that sector, the
owner of the sector is changed to 98 (unknown).

There is a way to gather reconnaissance data from planes.  Fly over a sector
of unknown designation.  Then do a 'v' to view the sector.  This has to be
done in a particular manner.  For example, suppose you suspect your
neighbor's capital is somewhere around 3 to 4 sectors to the east of
one of your airfields.  You could find out like this:
	fly 24,-10 1 0
	<24.2:1:0:24,-10> rrr
	<21.2:1:0:27,-10> v
	Now over completely constructed technical center.
	<20.2:1:0:27,-10> d
	<19.2:1:0:27,-9> v
	Now over completely constructed capital.
	<18.2:1:0:27,-9> \llle
	1 plane landed.

Always put the 'v' on a separate line by itself.  Otherwise eupd
will update the wrong sectors.
@//E*O*F ./MAN/eupd.1//
chmod u=rw,g=r,o=r ./MAN/eupd.1
 
echo mkdir - ./_unix.O
mkdir ./_unix.O
chmod u=rwx,g=rx,o=rx ./_unix.O
 
echo x - ./_unix.O/genlib.a
sed 's/^@//' > "./_unix.O/genlib.a" <<'@//E*O*F ./_unix.O/genlib.a//'
@//E*O*F ./_unix.O/genlib.a//
chmod u=rw,g=r,o=r ./_unix.O/genlib.a
 
echo mkdir - ./hdrs
mkdir ./hdrs
chmod u=rwx,g=rx,o=rx ./hdrs
 
echo x - ./hdrs/emp.h
sed 's/^@//' > "./hdrs/emp.h" <<'@//E*O*F ./hdrs/emp.h//'
/* Copyright (c) 1985 by Thomas S. Fisher - Westminster, CO 80030 */

/*	Define BSD if you're building this on a 4.2 BSD system */
/*	Otherwise (for SysV), leave it undefined               */
/*	#define	BSD	*/

#define	MAXSCN	20
#define	XYMAX	64
#define	ERROR	-1
#define	OK	1

/*
 *  Sector Record
 */

#define	CIV	0
#define	MIL	1
#define	SHL	2
#define	GUN	3
#define	PLN	4
#define	ORE	5
#define	BAR	6

struct  sector {
	int	s_secno;
	char	s_des;
	char	s_flag;
	int	s_coun;
	int	s_date;
	char	s_ckpt;
	char	s_def;
	int	s_eff;
	int	s_min;
	int	s_gold;
	int	s_mob;
	int	s_rsrc[7];
	int	s_prod;
	char	s_del[7];
	char	s_rsrvd[9];
	} ;

/*
 *
 */
@//E*O*F ./hdrs/emp.h//
chmod u=rw,g=r,o=r ./hdrs/emp.h
 
echo x - ./hdrs/ship.h
sed 's/^@//' > "./hdrs/ship.h" <<'@//E*O*F ./hdrs/ship.h//'
	/* ship types */
#define	S_PT	0
#define	S_MIN	1
#define	S_DES	2
#define	S_SUB	3
#define	S_FRE	4
#define	S_TEN	5
#define	S_BAT	6
#define	S_CAR	7
#define	TMAXNO	7

struct	shpstr {
	char    shp_own;            /* country # of owner */
	char    shp_type;           /* ship type */
	char    shp_effc;           /* 0 - 100 */
	short   shp_xp, shp_yp;     /* location in abs coords */
	char    shp_fleet;          /* group membership */
	char    shp_crew;           /* military | civvies on board */
	char    shp_shels;          /* shells on board */
	char    shp_gun;            /* etc */
	char    shp_plns;
	char    shp_or;
	char    shp_gld;
	char    shp_spric;          /* ship price, if for sale */
	char    shp_mbl;            /* mobility */
	int     shp_lstp;           /* time of last update */
};
@//E*O*F ./hdrs/ship.h//
chmod u=rw,g=r,o=r ./hdrs/ship.h
 
echo mkdir - ./EHELP
mkdir ./EHELP
chmod u=rwx,g=rx,o=rx ./EHELP
 
echo x - ./EHELP/ehelp.c
sed 's/^@//' > "./EHELP/ehelp.c" <<'@//E*O*F ./EHELP/ehelp.c//'
/* Copyright (c) 1985 by Thomas S. Fisher - Westminster, CO 80030 */

/*
	There are a variety of fflush and sleep calls in here to fix(?) 
	some of the problems with terminals running at 9600 baud on an
	Amdahl UTS system.
*/

#include	<stdio.h>
#include	<ctype.h>
#include	"emp.h"
#include	"ship.h"
/*
	There are two ways of handling raw mode in here: one for 4.2 BSD
	and one for SysV.  The BSD symbol in emp.h must be defined if this
	is being built on a 4.2 system.
*/
#ifdef	BSD
#include	<sgtty.h>
#else
#include	<termio.h>
#endif	BSD

#define	MAXLINE	132	/* Max command line (at bottom of screen) length */
#define	MAXPATH	64	/* Max path for nav and mov */

/* Miscellaneous constants */

#define	OK	1
#define	RESET	0
#define	TRUE	1
#define	FALSE	0

/* Special characters while cursor is on the map */

#define	DELETE	077
#define	CR	015
#define	LF	012
#define	SPACE	' '
#define	PLUS	'+'
#define	MINUS	'-'
#define	TAB	011

/*	Screen motion characters	*/

#define	UP	'e'
#define	UPRIGHT	'r'
#define	RIGHT	'd'
#define	DNRIGHT	'c'
#define	DOWN	'x'
#define	DNLEFT	'z'
#define	LEFT	's'
#define	UPLEFT	'w'
#define VILEFT	'h'
#define	VIDN	'j'
#define	VIUP	'k'
#define	VIRIGHT	'l'

#define	CENSW	15	/* Width of census display area */

/* Valid command codes */

#define	CEN	1
#define	DES	2
#define	MOV	3
#define	DEL	4
#define	MAP	5
#define	SHP	6
#define	NAV	7
#define	NCMDS	7

FILE	*fopen(), *fdsec, *fdscrpt, *fdship;
struct	sector	s;
struct	shpstr	Ship;
int	Func = CEN;
char	Stype[] = { 'p', 'm', 'd', 's', 'f', 't', 'b', 'c' };
char	*Sorder = "cbdtspmf";
char	Shiplist[128];
int	Shpnum = 0;
char    *Fchar[] = { " ", "cen", "des", "mov", "del", "map", "shi", "nav" };
char	*Deldir[] = { ".",  "$",  "",   "",
		      "",   "",   "",   "",
		      "n",  "ne", "e",  "se",
		      "s",  "sw", "w",  "nw" };
char	*Movdir[] = {	"\\l",	"l",	"/l",	"u",
		"e",	"d",	"/r",	"r",	"\\r" };


int	Rtxlat[] = { 15, 14, 13, 8, 0, 12, 9, 10, 11 };
char	Rtdirl[] = { ' ', '$', ' ', ' ', ' ', ' ', ' ', ' ',
		     '^', ' ', ' ', ' ', 'v', '/', '<', '\\' };
char	Rtdirr[] = { ' ', '$', ' ', ' ', ' ', ' ', ' ', ' ',
		     '^', '/', '>', '\\', 'v', ' ', ' ', ' ' };
char	Desig = 'g';
int	Thresh = 0;
int	Rsrc = ORE;
int	Quant = 0;
char	Rchar[] = { 'c', 'm', 's', 'g', 'p', 'o', 'b' };
int	Pathl = 0;
int	Pathx[MAXPATH], Pathy[MAXPATH];
int	Xcen = 0, Ycen = 0;
int	Xcur = 0, Ycur = 0;
int	Xl, Yl, Xh, Yh, Xlast, Ylast;
char	linebuf[MAXLINE];

#ifdef	BSD
struct	sgttyb	tty0, ttyb;
#else
struct	termio	st, st0;
#endif	BSD

char	tbuf[BUFSIZ], tcapbuf[50];
char	*CL, *CM;
int	Termh, Termw, Censtrt;
int	Foe;
#undef	putchar
int	putchar();

main() {
	char	*prompt();
	char	funcstr[4], *getenv(), *foestr;
	int	i;

	if( (fdsec = fopen("empsect", "r")) == NULL ) {
		fprintf(stderr, "Can't open empsect\n");
		exit(1);
	}
	if( (fdscrpt = fopen(".yout", "a+")) == NULL ) {
		fprintf(stderr, "Can't open output file\n");
		exit(2);
	}
	fdship = fopen("empship", "r");
	if( (foestr = getenv("FOES")) == NULL ) {
		Foe = 0;
	} else {
		Foe = atoi(foestr);
	}
#ifdef	BSD
	ioctl(0, TIOCGETP, &tty0);	/* save terminal state 4.2BSD */
#else
	ioctl(0, TCGETA, &st0);		/* save terminal state */
#endif	BSD
	getcap();
	clrscrn();
	rawmode();
	ckdmode();
	prfunc();
	prcoord();
	strcpy(Shiplist,",");
	while( prompt(">") != NULL ) {
		if( linebuf[0] == '>' ) { 
			fputs(&linebuf[1], fdscrpt);
			continue;
		}
		if( sscanf(linebuf, "%d,%d%*[^\n]\n", &Xcen, &Ycen) == 2 ) {
			prcoord();
			Xcur = Xcen;
			Ycur = Ycen;
			continue;
		}
		if( sscanf(linebuf, "%3s%*[^\n]\n", funcstr) != 1 ) continue;
		for( i = 1; i <= NCMDS; i++ ) {
			if( strncmp(funcstr, Fchar[i], 3) != 0 ) continue; 
			Func = i;
			prfunc();
			fflush(stdout);
			switch( Func ) {
			case CEN:
				docen();
				break;
			case DES:
				dodes();
				break;
			case MOV:
				domov();
				break;
			case DEL:
				dodel();
				break;
			case MAP:
				prmap();
				break;
			case SHP:
				doship();
				break;
			case NAV:
				donav();
				break;
			}
			break;
		}
	}
	mvcrsr(Termh, 1);
#ifdef	BSD
	ioctl(0, TIOCSETN, &ttyb); /* restore terminal state and exit 4.2BSD */
#else
	ioctl(0, TCSETAF, &st0);   /* restore terminal state and exit */
#endif	BSD
}

getcap()
{
	extern	short	ospeed;
	char *ap;
	char	*getenv(), *tgetstr();
	char *term;

	term = getenv("TERM");
	if(term == NULL) {
		fprintf(stderr, "No TERM in environment\n");
		exit(1);
	}
	switch(tgetent(tbuf, term)) {
	case -1:
		fprintf(stderr, "Cannot open termcap file\n");
		exit(2);
	case 0:
		fprintf(stderr, "%s: unknown terminal", term);
		exit(3);
	}

	ap = tcapbuf;

	Termh = tgetnum("li");
	Termw = tgetnum("co");
	Censtrt = Termw - CENSW;

	CL = tgetstr("cl", &ap);
	CM = tgetstr("cm", &ap);

	if (Termh <= 0 || Termw <= 0) {
		fprintf(stderr, "Must know the screen size\n");
		exit(5);
	}
#ifdef	BSD
	ospeed = ttyb.sg_ospeed & 017;
#else
	ospeed = st0.c_cflag & CBAUD;
#endif	BSD
}

char	*
prompt(s)
char	*s;
{
	static	int	plength, ilength;
	int	i, blanks;
	char	*ret;

	blanks = plength + ilength;
	for( i = 0; i < blanks; i++ ) {
		linebuf[i] = ' ';
	}
	linebuf[blanks] = '\0';
	mvcrsr(Termh-1, 1);
	printf("%s", linebuf);
	mvcrsr(Termh-1, 1);
	printf("%s", s);
	plength = strlen(s);
	ret = fgets(linebuf, MAXLINE, stdin);
	ilength = strlen(linebuf);
	return(ret);
}

rawmode()
{
#ifdef	BSD
	ioctl(0, TIOCGETP, &ttyb);
	ttyb.sg_flags &= ~ECHO;
	ttyb.sg_flags |= RAW;
	ioctl(0, TIOCSETN, &ttyb);
#else
	ioctl(0, TCGETA, &st);
	st.c_iflag &= ~(INLCR | ICRNL | BRKINT);
	st.c_oflag |= OPOST;
	st.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
	st.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOK | ECHONL);
	st.c_cc[VMIN] = '\01';
	st.c_cc[VTIME] = '\00';
	ioctl(0, TCSETA, &st);
#endif	BSD
/*
	Now in raw mode
*/
}

ckdmode()
{
#ifdef	BSD
	ioctl(0, TIOCGETP, &ttyb);
	ttyb.sg_flags |= ECHO;
	ttyb.sg_flags &= ~RAW;
	ioctl(0, TIOCSETN, &ttyb);
#else
	ioctl(0, TCGETA, &st);
	st.c_iflag |=  ICRNL;
	st.c_lflag |= (ICANON | ECHO);
	st.c_cc[VMIN] = st0.c_cc[VMIN];
	st.c_cc[VTIME] = st0.c_cc[VTIME];
	ioctl(0, TCSETA, &st);
#endif	BSD
/*
	Now in cooked mode
*/
}

mvcrsr(row, col)
short	row, col;
{
	fflush(stdout);
	printf("%s", tgoto(CM, col-1, row-1));
}

clrscrn() {
	mvcrsr(1, 1);
	tputs(CL, Termh, putchar);
	fflush(stdout);
}

docen()
{
	char	c, onmap();

	while( prompt("cen>") != NULL ) {
		if( linebuf[0] == '.' ) break;
		if( linebuf[0] != '\n' ) continue;
		while( (c = onmap()) != '\n' ) {
			if( c == SPACE ) {
				fprintf(fdscrpt, "cen %d,%d\n", Xcur, Ycur);
			}
			if( c == TAB ) prfcen();
		}
	}
}

dodes()
{
	char	c, desstr[4], onmap();

	prdes();
	while( prompt("des>") != NULL ) {
		if( linebuf[0] == '.' ) break;
		if( sscanf(linebuf, "%1[abcdfghimrtuwx#*!)+-]%*[^\n]\n",
			desstr) == 1 ) {
			if( desstr[0] != '\0' ) {
				Desig = desstr[0];
				prdes();
				linebuf[0] = '\n';
			}
		}
		if( linebuf[0] != '\n' ) continue;
		while( (c = onmap()) != '\n' ) {
			if( c == SPACE ) {
				fprintf(fdscrpt, "des %d,%d %c\n",
					Xcur, Ycur, Desig);
				putchar( Desig );
			}
			if( c == TAB ) prfcen();
		}
	}
}

domov()
{
	int	 ret;
	char	c, onmap();

	Pathl = 0;
	prrsrc();
	prquant();
	while( prompt("mov>") != NULL ) {
		if( linebuf[0] == '.' ) break;
		if( sscanf(linebuf, "%d%*[^\n]\n", &Quant) == 1 ) {
			prquant();
			linebuf[0] = '\n';
		}
		if( (ret = getrsrc()) != ERROR ) {
			Rsrc = ret;
			prrsrc();
			linebuf[0] = '\n';
		}
		if( linebuf[0] != '\n' ) continue;
		while( (c = onmap()) != '\n' ) {
			switch( c ) {
			case TAB:
				prfcen();
				break;
			case PLUS:
				addsec();
				break;
			case MINUS:
				delsec();
				getsec(&s, secno(Xcur, Ycur));
				break;
			case SPACE:
				if( Pathl == 0 && Quant > 0 ) break;
				if( addsec() != OK ) break;
				fprintf(fdscrpt, "mov %c %d,%d %d ",
					Rchar[Rsrc], Pathx[0], Pathy[0], Quant);
				mvcrsr((Pathy[0]-Yl+1), (Pathx[0]-Xl)*3+2);
				if( Quant == 0 ) {
					fprintf(fdscrpt, "\n");
					delsec();
					break;
				}
				moveit();
				fprintf(fdscrpt, "v\ne\n");
				break;
			}
		}
	}
}

dodel()
{
	int	ret, index, ix, iy;
	char	c, onmap();

	prrsrc();
	prthresh();
	while( prompt("del>") != NULL ) {
		if( linebuf[0] == '.' ) break;
		if( sscanf(linebuf, "%d%*[^\n]\n", &Thresh) == 1 ) {
			prthresh();
			linebuf[0] = '\n';
		}
		if( (ret = getrsrc()) != ERROR ) {
			Rsrc = ret;
			prmap();
			prrsrc();
			prthresh();
			linebuf[0] = '\n';
		}
		if( linebuf[0] != '\n' ) continue;
		while( (c = onmap()) != '\n' ) {
			switch( c ) {
			case TAB:
				prfcen();
				break;
			case PLUS:
				addsec();
				break;
			case SPACE:
				if( adjacent(Xcur, Ycur, Xlast, Ylast) != OK ) break;
				fprintf(fdscrpt, "del %c %d,%d\n%d,%d (%d)\n",
					Rchar[Rsrc], Xlast, Ylast, Xcur, Ycur, Thresh);
				ix = Xcur - Xlast;
				if( ix < -1 ) ix += XYMAX;
				if( ix >  1 ) ix -= XYMAX;
				iy = Ycur - Ylast;
				if( iy < -1 ) iy += XYMAX;
				if( iy >  1 ) iy -= XYMAX;
				index = (ix + 1)*3 + (iy + 1);
				mvcrsr(Ylast - Yl + 1, (Xlast - Xl)*3 + 1);
				putchar(Rtdirl[Rtxlat[index]]);
				mvcrsr(Ylast - Yl + 1, (Xlast - Xl)*3 + 3);
				putchar(Rtdirr[Rtxlat[index]]);
				addsec();
				break;
			}
		}
	}
}

getrsrc()
{
	int	i;
	char	rstr[4];

	if( sscanf(linebuf, "%1[cmsgpob]%*[^\n]\n", rstr) != 1 ) {
		return(ERROR);
	}
	if( rstr[0] == '\0' ) return(ERROR);
	for( i = 0; i <= BAR; i++ ) {
		if( rstr[0] == Rchar[i] ) return(i);
	}
	return(ERROR);
}

doship()
{
	int	x, y, row, col, i;
	int	shipok;
	char	c, sorder[TMAXNO+1];

	if( fdship == NULL ) return;
	prorder();
	prshpnum();
	while( prompt("ship>") != NULL ) {
		shipok = ERROR;
		for( i = 0; i <= TMAXNO; i++ ) {
			sorder[i] = ' ';
		}
		if( linebuf[0] == '.' ) break;
		if( sscanf(linebuf, "%d%*[^\n]\n", &Shpnum) == 1 ) {
			prshpnum();
			shipok = OK;
		}
		sscanf(linebuf, "%8[pmdsftbcPMDSFTBC]%*[^\n]\n", sorder);
		for( i = 0; i <= TMAXNO; i++ ) {
			if( sorder[i] == '\0' || sorder[i] == ' ' ) break;
			Sorder[i] = tolower(sorder[i]);
		}
		if( sorder[0] != '\0' && sorder[0] != ' ' ) {
			Sorder[i] = '\0';
			prorder();
			shipok = OK;
		}
		if( linebuf[0] == '*' && linebuf[1] == '\n' ) {
			strcpy(Sorder, "cbdtspmf");
			prorder();
			shipok = OK;
		}
		if( linebuf[0] == '?' && linebuf[1] == '\n' ) {
			rewind(fdship);
			while( fread(&Ship, sizeof(struct shpstr), 1, fdship) == 1 ) {
				if( Ship.shp_effc == 0 ) continue;
				if( Foe != 0 && Ship.shp_own != 0 &&
					Ship.shp_own != Foe ) continue;
				for( i = 0; i <= TMAXNO && Sorder[i]!='\0'; i++ ) {
					if( Sorder[i] == Stype[Ship.shp_type])  break;
				}
				if( Sorder[i] != Stype[Ship.shp_type]) continue;
				x = Ship.shp_xp;
				if( (Xcen - x) >= XYMAX/2 ) x += XYMAX;
				if( (x - Xcen) >= XYMAX/2 ) x -= XYMAX;
				if( x < Xl || x > Xh ) continue;
				y = Ship.shp_yp;
				if( (Ycen - y) >= XYMAX/2 ) y += XYMAX;
				if( (y - Ycen) >= XYMAX/2 ) y -= XYMAX;
				if( y < Yl || y > Yh ) continue;
				row = y - Yl + 1;
				col = (x - Xl)*3 + 1;
				if( Ship.shp_own == 0 ) col += 2;
				mvcrsr(row, col);
				putchar(toupper(Stype[Ship.shp_type]));
			}
			shipok = OK;
		}
		if( shipok == OK ) linebuf[0] = '\n';
		if( linebuf[0] != '\n' ) continue;
		while( (c = onmap()) != '\n' ) {
			switch( c ) {
			case '\t':
				prship();
				break;
			case 'i':
				prshplst();
				break;
			case 'I':
				prshpsum();
				break;
			}
		}
	}
}

donav()
{
	int	shipok;
	char	c, onmap();

	Pathl = 0;
	prorder();
	prshpnum();
	while( prompt("nav>") != NULL ) {
		shipok = ERROR;
		if( linebuf[0] == '.' ) break;
		if( linebuf[0] == '\n' )	;
		else if( linebuf[0] == ',' ) {
			strcpy(Shiplist,",");
			shipok = OK;
		}
		else if( isalpha(linebuf[0]) ) {
			Shiplist[0] = linebuf[0];
			Shiplist[1] = '\0';
			shipok = OK;
		}
		else if( sscanf(linebuf,"%120[0123456789/]",Shiplist) == 1 ) {
			if( Shiplist[0] != '\0' &&
				sscanf(Shiplist,"%d",&Shpnum) == 1 ) shipok=OK;
		}
		if( shipok == OK ) {
			linebuf[0] = '\n';
			prnav();
		}
		if( linebuf[0] != '\n' ) continue;
		while( (c = onmap()) != '\n' ) {
			switch(c) {
			case TAB:
				prship();
				break;
			case 'i':
				prshplst();
				break;
			case 'I':
				prshpsum();
				break;
			case PLUS:
				addsec();
				break;
			case MINUS:
				delsec();
				break;
			case SPACE:
				if( Pathl == 0 ) break;
				if( addsec() != OK ) break;
				if( strchr(Shiplist, ',') != NULL ) {
					sprintf(Shiplist, "%d,%d",
						Pathx[0], Pathy[0]);
				}
				fprintf(fdscrpt,"nav %s ", Shiplist);
				moveit();
				fprintf(fdscrpt, "\ne\n");
				break;
			}
		}
	}
}

moveit()
{
	int	i, ix, iy, row, col;

	row = Pathy[0] - Yl + 1;
	col = (Pathx[0] - Xl)*3 + 2;
	mvcrsr(row, col);
	putchar('@');
	mvcrsr(row, col);
	for( i = 1; i < Pathl; i++ ) {
		ix = Pathx[i] - Pathx[i-1];
		if( ix < -1 ) ix += XYMAX;
		if( ix >  1 ) ix -= XYMAX;
		iy = Pathy[i] - Pathy[i-1];
		if( iy < -1 ) iy += XYMAX;
		if( iy >  1 ) iy -= XYMAX;
		fprintf(fdscrpt, "%s", Movdir[(ix+1)*3 + (iy+1)]);
		row = Pathy[i] - Yl + 1;
		col = (Pathx[i] - Xl)*3 + 2;
		mvcrsr(row, col);
		putchar('@');
		mvcrsr(row, col);
	}
}

prfunc()
{
	mvcrsr(1, Censtrt);
	printf("Func: %-3s", Fchar[Func]);
}

prcoord()
{
	mvcrsr(2, Censtrt);
	printf("Center: %3d,%-3d", Xcen, Ycen);
}

prdes()
{
	mvcrsr(3, Censtrt);
	printf("Desig: %c      ", Desig);
}

prrsrc()
{

	mvcrsr(3, Censtrt);
	printf("Resource: %c   ", Rchar[Rsrc]);
}

prthresh()
{
	mvcrsr(4, Censtrt);
	printf("Thresh: %-3d", Thresh);
}

prquant()
{
	mvcrsr(4, Censtrt);
	printf("Quant: %-4d", Quant);
}

prorder()
{
	mvcrsr(3, Censtrt);
	printf("Order %-8s", Sorder);
}

prshpnum()
{
	mvcrsr(4, Censtrt);
	printf("Ship: %-5d", Shpnum);
}

prnav()
{
	char	*p, out[8];
	int	i;

	mvcrsr(4, Censtrt);
	p = Shiplist;
	for( i = 0; i < 7; i++ ) {
		if( *p == '\0' || *p == '/' ) break;
		out[i] = *p++;
	}
	out[i] = '\0';
	printf("Ship: %-5s", out);
}

prship()
{
	short	mbl;

	if( getship(&Ship, Shpnum) == ERROR ) return;
	mvcrsr(5, Censtrt);
	printf("               ");
	mvcrsr(6, Censtrt);
	printf("%c%5d,%-3d %3d ",
		toupper(Stype[ Ship.shp_type ]),
		Ship.shp_xp,	Ship.shp_yp,
		Ship.shp_own);
	mvcrsr(7, Censtrt);
/* kluge to handle unsigned characters (so ship.h doesn't have to change) */
	if( (mbl = Ship.shp_mbl) > 127 ) mbl -= 256;
	printf("%3d%%  %c    %3d ",
		Ship.shp_effc,
		Ship.shp_fleet,
		mbl);
	mvcrsr(8, Censtrt);
	if( Ship.shp_type == S_CAR ) {
		printf("%3d %3d %2d %3d ", 
			Ship.shp_crew,	Ship.shp_shels,
			Ship.shp_gun,	Ship.shp_plns);
	} else {
		printf("%3d %3d %2d      ", 
			Ship.shp_crew,	Ship.shp_shels,
			Ship.shp_gun);

	}
}

prshpsum()
{
	int	num, frlist[TMAXNO+1], foelist[TMAXNO+1];
	int	i;

	rewind( fdship );
	num = 0;
	for( i = 0; i <= TMAXNO; i++ ) {
		frlist[i] = foelist[i] = 0;
	}
	while( getship(&Ship, num++) != ERROR ) {
		if( Ship.shp_effc == 0 ) continue;
		if( (Ship.shp_xp - Xcur)%XYMAX != 0 ) continue;
		if( (Ship.shp_yp - Ycur)%XYMAX != 0 ) continue;
		if( Foe != 0 && Ship.shp_own != 0 &&
			Foe != Ship.shp_own ) continue;
		if( Ship.shp_own == 0 ) {
			frlist[Ship.shp_type]++;
		} else {
			foelist[Ship.shp_type]++;
		}
	}
	mvcrsr(5, Censtrt);
	printf("%2.0dc %2.0db %2.0dd %2.0dt",
		frlist[S_CAR], frlist[S_BAT], frlist[S_DES], frlist[S_TEN]);
	mvcrsr(6, Censtrt);
        printf("%2.0ds %2.0dp %2.0dm %2.0df",
                frlist[S_SUB], frlist[S_PT ], frlist[S_MIN], frlist[S_FRE]);
	mvcrsr(7, Censtrt);
        printf("%2.0dc %2.0db %2.0dd %2.0dt",
                foelist[S_CAR], foelist[S_BAT], foelist[S_DES], foelist[S_TEN]);
	mvcrsr(8, Censtrt);
        printf("%2.0ds %2.0dp %2.0dm %2.0df",
                foelist[S_SUB], foelist[S_PT ], foelist[S_MIN], foelist[S_FRE]);
}

prshplst()
{
	int	num, field, frfld, foefld;
	int	i;

	rewind(fdship);
	num = 0;
	frfld = 0;
	foefld = 21;
	while( getship(&Ship, num++) != ERROR ) {
		if( Ship.shp_effc == 0 ) continue;
		if( (Ship.shp_xp - Xcur)%XYMAX != 0 ) continue;
		if( (Ship.shp_yp - Ycur)%XYMAX != 0 ) continue;
		if( Foe != 0 && Ship.shp_own != 0 &&
			Foe != Ship.shp_own ) continue;
		for( i=0; i<=TMAXNO && Sorder[i]!='\0'; i++ ) {
			if( Sorder[i] == Stype[Ship.shp_type])  break;
		}
		if( Sorder[i] != Stype[Ship.shp_type])  continue;
		if( Ship.shp_own == 0 ) {
			field = (frfld > 20) ? 20 : frfld++;
		} else {
			field = (foefld > 41) ? 41 : foefld++;
		}
		mvcrsr(10 + field/3, Censtrt + (field%3)*5); 
		printf("%c%-4d",Stype[Ship.shp_type], num-1); 
	}
	for( ; frfld <= 20; frfld++ ) {
		mvcrsr(10 + frfld/3, Censtrt + (frfld%3)*5); 
		printf("     ");
	}
	for( ; foefld <= 41; foefld++ ) {
		mvcrsr(10 + foefld/3, Censtrt + (foefld%3)*5); 
		printf("     ");
	}
}

addsec()
{
	int	i;

	if( Func == MOV || Func == NAV ) {
		i = (Pathl == 0) ? 0 : Pathl - 1;
		if( Pathl != 0 &&
		    adjacent(Xcur,Ycur,Pathx[i],Pathy[i]) != OK ) {
			return(ERROR);
		}
		if( Pathl == 0 || Xcur != Pathx[i] || Ycur != Pathy[i] ) {
			Pathx[Pathl] = Xcur;
			Pathy[Pathl] = Ycur;
			Pathl++;
			putchar('@');
		}
	}
	Xlast = Xcur;
	Ylast = Ycur;
	return(OK);
}

delsec()
{
	if( Func == MOV || Func == NAV ) {
		getsec(&s, secno(Xcur, Ycur));
		putchar(s.s_des);
		if( Pathl <= 0 ) return;
		Pathl--;
		if( Pathl <= 0 ) return;
		Xcur = Pathx[Pathl-1];
		Ycur = Pathy[Pathl-1];
	}
}

adjacent(x, y, xl, yl)
int	x, y, xl, yl;
{
	int	xdiff, ydiff;

	xdiff = x - xl;
	if( xdiff < 0 ) xdiff = -xdiff;
	if( xdiff == (XYMAX-1) ) xdiff = 1;
	ydiff = y - yl;
	if( ydiff < 0 ) ydiff = -ydiff;
	if( ydiff == (XYMAX-1) ) ydiff = 1;
	if( (xdiff == 0 || xdiff == 1) &&
	    (ydiff == 0 || ydiff == 1) ) return(OK);
	return(ERROR);
}

prmap()
{
	int	height, width, xm, ym, row, col, nosect;

	clrscrn();
	prfunc();
	prcoord();
	fflush(stdout);
	sleep(1); /* to make some terminals work at 9600 baud */
	height = Termh - 3;
	width = Termw - CENSW - 4;
	row = 1;
	Yl = Ycen - height/2;
	Yh = Ycen + height/2;
	Xl = Xcen - width/6;
	Xh = Xcen + width/6;
	for( ym = Yl; ym <= Yh; ym++ ) {
		col = 1;
		nosect = TRUE;
		for( xm = Xl; xm <= Xh; xm++ ) { 
			getsec(&s, secno(xm, ym));
			if( s.s_des != '\0' && s.s_des != ' ' ) {
				if( nosect == TRUE ) {
					mvcrsr(row, col);
					nosect = FALSE;
				}
				if( s.s_coun != 0 && s.s_coun != 99 ) {
					if( s.s_des != '?' ) {
						if(Foe==0 || s.s_coun==98) {
							putchar('?');
						} else {
							printf("%1d",
								s.s_coun%10);
						}
					} else {
						putchar(' ');
					}
					putchar(s.s_des);
					putchar(' ');
				} else if( s.s_coun == 99 ) {
					putchar('~');
					putchar(s.s_des);
					putchar(' ');
				} else if( s.s_coun == 0 ) {
					if( Func == DEL ) {
						putchar(Rtdirl[(int)(s.s_del[Rsrc]&017)]);
					} else {
						putchar(' ');
					}
					if( s.s_des == '.' && s.s_rsrc[SHL] != 0 ) {
						putchar(':');
					} else {
						putchar(s.s_des);
					}
					if( Func == DEL ) {
						putchar(Rtdirr[(int)(s.s_del[Rsrc]&017)]);
					} else {
						putchar(' ');
					}
				}
			} else {
				nosect = TRUE;
			}
			col += 3;
		}
	row++;
	}
	mvcrsr((Ycen - Yl), (Xcen - Xl)*3);
}

prcen()
{
	char	amntstr[8], thstr[8];
	int	i, xcur, ycur;

	xcur = Xcur;  ycur = Ycur;
	if( Xcur < -XYMAX/2 ) xcur = Xcur + XYMAX;
	if( Xcur >  XYMAX/2 ) xcur = Xcur - XYMAX;
	if( Ycur < -XYMAX/2 ) ycur = Ycur + XYMAX;
	if( Ycur >  XYMAX/2 ) ycur = Ycur - XYMAX;
	mvcrsr(9, Censtrt);
	if( s.s_des == '\0' ) s.s_des = ' ';
	printf("%c%5d,%-3d %3d", s.s_des, xcur, ycur, s.s_coun);
}

prfcen()
{
	int	i, thrsh;
	char	amntstr[8], thstr[8];

	mvcrsr(10, Censtrt);
	printf("               ");
	mvcrsr(11, Censtrt);
	printf("%3d%%%10d", s.s_eff, s.s_mob);
	mvcrsr(12, Censtrt);
	printf("m%4d   gm%4d", s.s_min, s.s_gold);
	mvcrsr(13, Censtrt);
	printf("               ");
	for( i = 0; i <= BAR; i++ ) {
		mvcrsr(14+i, Censtrt);
		sprintf(amntstr, "%d", s.s_rsrc[i]);
		if( *amntstr == '0' ) *amntstr = '.';
		thrsh = (s.s_del[i] >> 4) & 017;
		thrsh *= 8;
		if( s.s_des == 'u' && i == CIV ) thrsh *= 10;
		if( s.s_des == 'b' && i == BAR ) thrsh *= 4;
		if( s.s_des == 'w' && (i==SHL || i==GUN ||
			i==ORE) ) thrsh *= 10;
		sprintf(thstr, "%d ", thrsh);
		if( *thstr == '0' ) *thstr = '.';
		printf("%c%5s%3s%5s ", Rchar[i], amntstr, Deldir[(int)(s.s_del[i]&017)], thstr);
	}
	mvcrsr(22, Censtrt);
	printf("prod%4d    %c%c", s.s_prod, s.s_ckpt, s.s_def);
}

char
onmap()
{
	int	row, col;
	char	c;

	rawmode();
	if( Func != SHP ) {
		getsec(&s, secno(Xcur, Ycur));
		prcen();
	}
	row = Ycur - Yl + 1;
	col = (Xcur - Xl)*3 + 2;
	mvcrsr(row, col);
	while( c = getchar() ) {
		switch( c ) {
		case LF:
		case CR:
			ckdmode();
			return('\n');
		case TAB:
		case 'i':
		case 'I':
		case PLUS:
		case MINUS:
		case SPACE:
			return(c);
		}
		switch( c ) {
		case UPLEFT:
		case LEFT  :
		case DNLEFT:
		case VILEFT:
			if( Xcur <= Xl ) break;
			Xcur--;
			col -= 3;
			break;
		case UPRIGHT:
		case RIGHT  :
		case DNRIGHT:
		case VIRIGHT:
			if( Xcur >= Xh ) break;
			Xcur++;
			col += 3;
			break;
		case DOWN:
		case UP:
		case VIDN:
		case VIUP:
			break;
		default:
			continue;
		}
		switch( c ) {
		case UPLEFT:
		case UP    :
		case UPRIGHT:
		case VIUP:
			if( Ycur <= Yl ) break;
			Ycur--;
			row--;
			break;
		case DNLEFT:
		case DOWN  :
		case DNRIGHT:
		case VIDN:
			if( Ycur >= Yh ) break;
			Ycur++;
			row++;
			break;
		}
		getsec(&s, secno(Xcur, Ycur));
		prcen();
		mvcrsr(row, col);
	}
}
@//E*O*F ./EHELP/ehelp.c//
chmod u=rw,g=r,o=r ./EHELP/ehelp.c
 
echo x - ./EHELP/Makefile
sed 's/^@//' > "./EHELP/Makefile" <<'@//E*O*F ./EHELP/Makefile//'
INSDIR=..
LIBDIR=../_unix.O
GENLIB=$(LIBDIR)/genlib.a
TERMLIB=$(LIBDIR)/termlib.a
HDRDIR=../hdrs
HEADERS= \
	$(HDRDIR)/emp.h \
	$(HDRDIR)/ship.h
CFLAGS= -c -O

ehelp:	$(INSDIR)/ehelp

$(INSDIR)/ehelp:	_unix.O/ehelp.o $(GENLIB) $(TERMLIB)
	$(CC) -o $(INSDIR)/ehelp _unix.O/ehelp.o $(GENLIB) $(TERMLIB)

_unix.O/ehelp.o:	ehelp.c $(HEADERS) 
	$(CC) $(CFLAGS) -I$(HDRDIR) ehelp.c
	@mv ehelp.o _unix.O/ehelp.o

clean:
	rm -f _unix.O/*.o

clobber:	clean
	rm -f $(INSDIR)/ehelp

FRC:
@//E*O*F ./EHELP/Makefile//
chmod u=rw,g=r,o=r ./EHELP/Makefile
 
echo mkdir - ./EHELP/_unix.O
mkdir ./EHELP/_unix.O
chmod u=rwx,g=rx,o=rx ./EHELP/_unix.O
 
echo x - ./EHELP/_unix.O/ehelp.o
sed 's/^@//' > "./EHELP/_unix.O/ehelp.o" <<'@//E*O*F ./EHELP/_unix.O/ehelp.o//'
@//E*O*F ./EHELP/_unix.O/ehelp.o//
chmod u=rw,g=r,o=r ./EHELP/_unix.O/ehelp.o
 
exit 0