[comp.sources.games] v01i075: xtrek - mulitplayer space war for X-windows, Part03/06

games-request@tekred.TEK.COM (07/02/87)

Submitted by: Chris Guthrie <chris%ic.Berkeley.EDU@ucbvax.berkeley.edu>
Comp.sources.games: Volume 1, Issue 75
Archive-name: xtrek/Part03


#! /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 archive 3 (of 6)."
# Contents:  detonate.c input.c newwin.c redraw.c
# Wrapped by billr@tekred on Thu Jul  2 10:26:30 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f detonate.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"detonate.c\"
else
echo shar: Extracting \"detonate.c\" \(2757 characters\)
sed "s/^X//" >detonate.c <<'END_OF_detonate.c'
X
X/*
X
X	Copyright (c) 1986 	Chris Guthrie
X
XPermission to use, copy, modify, and distribute this
Xsoftware and its documentation for any purpose and without
Xfee is hereby granted, provided that the above copyright
Xnotice appear in all copies and that both that copyright
Xnotice and this permission notice appear in supporting
Xdocumentation.  No representations are made about the
Xsuitability of this software for any purpose.  It is
Xprovided "as is" without express or implied warranty.
X
X*/
X
X#include <X/Xlib.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/ipc.h>
X#include <sys/shm.h>
X#include "defs.h"
X#include "struct.h"
X#include "data.h"
X
X/* Detonate torp */
X
X/*
X** Detonating torps have become a difficult part of the game.  Players
X** quickly learned that detonating their own torps when the cloud was
X** around another player, caused that player to die very quickly.  I
X** removed that feature because it lead to people not having to shoot
X** well to collect kills.  Now when players detonate their own torps,
X** the torps just vanish and become available for future firing.
X*/
X
Xdetmine()
X{
X    register int i;
X
X    if (me->p_flags & PFWEP) {
X	warning("Weapons overheated");
X	return;
X    }
X    for (i = 0; i < MAXTORP; i++) {
X	if (torps[i + (me->p_no * MAXTORP)].t_status == TMOVE) {
X	    torps[i + (me->p_no * MAXTORP)].t_status = TOFF;
X	}
X	else if (torps[i + (me->p_no * MAXTORP)].t_status == TSTRAIGHT) {
X	    torps[i + (me->p_no * MAXTORP)].t_status = TOFF;
X	}
X    }
X}
X
X/*
X** Here we have another flaw.  Detonating other players torps can be a
X** very quick way to die.  Why?  Because you always take some damage.
X** Experienced players never detonate other players' torps.  Balance is
X** really hard to obtain with this type of function.  Technically, a
X** player could nearly continuously detonate torps (at least faster than
X** they could be fired) and never be hurt, if I allowed less damage as
X** a possible result.  So here it sits.
X*/
X
Xdetothers()
X{
X    register int h, i;
X    int dx, dy;
X    register struct torp *j;
X
X    if (me->p_fuel < myship->s_detcost) {
X	warning("Not enough fuel to detonate");
X	return;
X    }
X    if (me->p_flags & PFWEP) {
X	warning("Weapons overheated");
X	return;
X    }
X    me->p_fuel -= myship->s_detcost;
X    me->p_wtemp += myship->s_detcost / 5;
X
X    for (h = 0; h < MAXPLAYER; h++) {
X	if ((players[h].p_status == PFREE) || (h == me->p_no))
X	    continue;
X	for (i = h * MAXTORP; i < MAXTORP * (h + 1); i++) {
X	    j = &torps[i];
X	    if ((j->t_status == TMOVE) || (j->t_status == TSTRAIGHT)) {
X		dx = j->t_x - me->p_x;
X		dy = j->t_y - me->p_y;
X		if (ABS(dx) > DETDIST || ABS(dy) > DETDIST) /* XXX */
X		    continue;
X		if (dx * dx + dy * dy < DETDIST * DETDIST)
X		    j->t_status = TDET;
X	    }
X	}
X    }
X}
END_OF_detonate.c
if test 2757 -ne `wc -c <detonate.c`; then
    echo shar: \"detonate.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f input.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"input.c\"
else
echo shar: Extracting \"input.c\" \(10383 characters\)
sed "s/^X//" >input.c <<'END_OF_input.c'
X
X/*
X
X	Copyright (c) 1986 	Chris Guthrie
X
XPermission to use, copy, modify, and distribute this
Xsoftware and its documentation for any purpose and without
Xfee is hereby granted, provided that the above copyright
Xnotice appear in all copies and that both that copyright
Xnotice and this permission notice appear in supporting
Xdocumentation.  No representations are made about the
Xsuitability of this software for any purpose.  It is
Xprovided "as is" without express or implied warranty.
X
X*/
X
X#include <X/Xlib.h>
X#include <stdio.h>
X#include <math.h>
X#include <sys/types.h>
X#ifdef hpux
X#include <time.h>
X#else hpux
X#include <sys/time.h>
X#endif hpux
X#include <signal.h>
X#include <errno.h>
X#include "defs.h"
X#include "struct.h"
X#include "data.h"
X
X#define WINSIDE 500
X
Xstatic int	doTheRedrawDude, skipUpdates = 1;
X
Xinitinput()
X{
X    XSelectInput(iconWin, ExposeWindow|ExposeRegion);
X    XSelectInput(w, 
X	KeyPressed|ButtonPressed|ButtonReleased|ExposeRegion|ExposeWindow);
X    XSelectInput(mapw, 
X	KeyPressed|ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(messagew, 
X	KeyPressed|ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(tstatw, ExposeWindow|ExposeRegion);
X    /*  May want this for a later refresh 
X    XSelectInput(war,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    */
X    XSelectInput(warf,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(warr,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(wark,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(waro,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(wargo,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(warno,
X	ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
X    XSelectInput(helpWin,ExposeRegion);
X    XSelectInput(planetw,ExposeRegion);
X    XSelectInput(playerw,ExposeRegion);
X}
X
XsetRedrawFlag()
X{
X	/* let the daemon know I'm real */
X	if (!watch)
X	    me->p_ghostbuster = 0;
X
X	if (skipUpdates)
X		doTheRedrawDude = 1;
X	else
X		doTheRedrawDude++;
X}
X
Xinput()
X{
X    XEvent data;
X    XKeyOrButtonEvent *tmp;
X    char *buf;
X    int nchar;
X    int fd;
X    struct itimerval	udt;
X
X    signal(SIGALRM, setRedrawFlag);
X    udt.it_interval.tv_sec = 0;
X    udt.it_interval.tv_usec = 200000;
X    udt.it_value.tv_sec = 0;
X    udt.it_value.tv_usec = 200000;
X    setitimer(ITIMER_REAL, &udt, 0);
X
X    tmp = (XKeyOrButtonEvent *) &data;
X
X    while (1) {
X	while (doTheRedrawDude-- > 0) {
X		intrupt();
X	}
X	while (!XPending()) {
X	    fd = (1 << dpyno());
X	    select(32, &fd, 0, 0, 0);
X	    while (doTheRedrawDude-- > 0)
X		intrupt();
X	}
X	XNextEvent(&data);
X	if ((!(copilot || watch)) && (me->p_updates > delay)) {
X	    me->p_flags &= ~(PFWAR);
X	}
X	switch ((int) data.type) {
X	    case KeyPressed:
X		if (inputIgnored())
X		    continue;
X		if ((me->p_flags & PFSELFDEST) && (!watch)) {
X		    me->p_flags &= ~PFSELFDEST;
X		    warning("Self Destruct has been canceled");
X		}
X		buf = XLookupMapping(&data, &nchar);
X		if (nchar > 0) {
X		    if (data.window == messagew)
X			smessage(*buf);
X		    else
X			keyaction(*buf, tmp);
X		}
X		break;
X	    case ButtonPressed:
X		if (inputIgnored())
X			continue;
X		if ((me->p_flags & PFSELFDEST) && (!watch)) {
X		    me->p_flags &= ~PFSELFDEST;
X		    warning("Self Destruct has been canceled");
X		}
X		if (data.window == warf) 
X		    waraction(tmp);
X		else if (data.window == warr) 
X		    waraction(tmp);
X		else if (data.window == wark) 
X		    waraction(tmp);
X		else if (data.window == waro) 
X		    waraction(tmp);
X		else if (data.window == wargo) 
X		    waraction(tmp);
X		else if (data.window == warno) 
X		    waraction(tmp);
X		else
X		    buttonaction(tmp);
X		break;
X	    case ExposeRegion:
X	    case ExposeWindow:
X		if (data.window == statwin && showStats)
X			redrawStats(statwin);
X		else if (data.window == tstatw)
X			redrawTstats();
X		else if (data.window == mapw)
X		    redrawall = 1;
X		else if (data.window == iconWin)
X		    drawIcon();
X		else if (data.window == helpWin)
X		    fillhelp();
X		else if (data.window == playerw)
X		    playerlist();
X		else if (data.window == planetw)
X		    planetlist();
X		break;
X	    default:
X		break;
X	}
X    }
X}
X
Xkeyaction(key, data)
Xchar key;
XXKeyOrButtonEvent *data;
X{
X    char buf[80];
X    unsigned char course;
X    struct obtype *gettarget(), *target;
X    struct player *p;
X    struct planet *pl;
X
X    if (watch && !index("LPSMiQ?hw ", key)) {
X	char	buf[BUFSIZ];
X
X	sprintf(buf, "'%c' command is not permitted in watch mode.", key);
X	warning(buf);
X	return;
X    }
X    switch(key) {
X	case '0':
X	case '1':
X	case '2':
X	case '3':
X	case '4':
X	case '5':
X	case '6':
X	case '7':
X	case '8':
X	case '9':
X	    set_speed(key - '0');
X	    break;
X	case 'k': /* k = set course */
X	    course = getcourse(data->window, data->x, data->y);
X	    set_course(course);
X	    me->p_flags &= ~(PFPLOCK | PFPLLOCK);
X	    break;
X	case 'p': /* p = fire phasers */
X	    course = getcourse(data->window, data->x, data->y);
X	    phaser(course);
X	    break;
X	case 't': /* t = launch torps */
X	    course = getcourse(data->window, data->x, data->y);
X	    ntorp(course, TMOVE, data->time);
X	    break;
X	case 'd': /* d = detonate other torps */
X	    detothers();
X	    break;
X	case 'D': /* D = detonate my torps */
X	    detmine();
X	    break;
X	case '+': /* + = Put shields up */
X	    shield_up();
X	    break;
X	case '-': /* - = Put shields down */
X	    shield_down();
X	    break;
X	case 'u': /* u = toggle shields */
X	case 's': /* For Serge */
X	    shield_tog();
X	    break;
X	case 'b': /* b = bomb planet */
X	    bomb_planet();
X	    break;
X	case 'z': /* z = beam up */
X	    beam_up();
X	    break;
X	case 'x': /* x = beam down */
X	    beam_down();
X	    break;
X	case 'R': /* R = Go into repair mode */
X	    me->p_flags &= ~(PFPLOCK | PFPLLOCK);
X	    repair();
X	    break;
X	case 'o': /* o = orbit nearest planet */
X	    me->p_flags &= ~(PFPLOCK | PFPLLOCK);
X	    orbit();
X	    break;
X	case 'Q':
X	    if (copilot || watch)
X		exit(1);
X	    me->p_flags |= PFSELFDEST;
X	    selfdest = me->p_updates + 100;
X	    warning("Self destruct initiated");
X	    break;
X	case '?': /* ? = Redisplay all messages */
X	    repeat_message();
X	    break;
X	case 'c': /* c = cloak */
X	    cloak();
X	    break;
X	case 'C': /* C = coups */
X	    coup();
X	    break;
X	case 'l': /* l = lock onto */
X	    /* since a robot would never use this function (it's user
X	       Interface dependent,) all the work is done here instead
X	       of in interface.c */
X	    target = gettarget(data->window, data->x, data->y,
X		TARG_PLAYER|TARG_PLANET);
X	    if (target->o_type == PLAYERTYPE) {
X		me->p_flags |= PFPLOCK;
X		me->p_flags &= ~(PFPLLOCK|PFORBIT|PFBEAMUP|PFBEAMDOWN|PFBOMB);
X		me->p_playerl = target->o_num;
X		p = &players[target->o_num];
X		sprintf(buf, "Locking onto %s (%c%d)",
X		    p->p_name,
X		    teamlet[p->p_team],
X		    p->p_no);
X		warning(buf);
X	    }
X	    else { 	/* It's a planet */
X		me->p_flags |= PFPLLOCK;
X		me->p_flags &= ~(PFPLOCK|PFORBIT|PFBEAMUP|PFBEAMDOWN|PFBOMB);
X		me->p_planet = target->o_num;
X		pl = &planets[target->o_num];
X		sprintf(buf, "Locking onto %s",
X		    pl->pl_name);
X		warning(buf);
X	    }
X	    break;
X	case '@': /* @ = toggle copilot permissions */
X	    me->p_flags ^= PFCOPILOT;
X	    break;
X	case '*': /* * = send in practice robot */
X	    practice_robo();
X	    break;
X
X	/* Start of display functions */
X	case ' ': /* ' ' = clear special windows */
X	    if (ismapped(playerw))
X		XUnmapWindow(playerw);
X	    if (ismapped(planetw))
X		XUnmapWindow(planetw);
X	    if (infomapped)
X		destroyInfo();
X	    if (ismapped(helpWin))
X		XUnmapWindow(helpWin);
X	    if (ismapped(war))
X		XUnmapWindow(war);
X	    break;
X	case 'L': /* L = Player list */
X	    if (ismapped(playerw)) {
X		XUnmapWindow(playerw);
X	    } else {
X		XMapWindow(playerw);
X	    }
X	    break;
X	case 'P': /* P = Planet list */
X	    if (ismapped(planetw)) {
X		XUnmapWindow(planetw);
X	    } else {
X		XMapWindow(planetw);
X	    }
X	    break;
X	case 'S': /* S = toggle stat mode */
X	   if (showStats) {
X		showStats = !showStats;
X		closeStats(statwin);
X	   } else {
X		statwin = openStats(me);
X		showStats = !showStats;
X	   }
X	   break;
X	case 'M': /* M = Toggle Map mode */
X	    mapmode = !mapmode;
X	    break;
X	case 'N': /* N = Toggle Name mode */
X	    namemode = !namemode;
X	    break;
X	case 'i': /* i = get information */
X	    if (!infomapped)
X		inform(data->window, data->x, data->y);
X	    else
X		destroyInfo();
X	    break;
X	case 'h': /* h = Map help window */
X	    if (ismapped(helpWin)) {
X		XUnmapWindow(helpWin);
X	    } else {
X		XMapWindow(helpWin);
X	    }
X	    break;
X	case 'w': /* w = map war stuff */
X	    if (copilot) {
X		warning("Copilots cannot alter war settings");
X		break;
X	    }
X	    if (ismapped(war))
X		XUnmapWindow(war);
X	    else
X		warwindow();
X	    break;
X	default:
X	    XFeep(0);
X	    break;
X    }
X}
X
Xbuttonaction(data)
XXKeyOrButtonEvent *data;
X{
X    unsigned char course;
X    struct obtype *gettarget(), *target;
X
X    if (watch) {	/* Special case */
X	target = gettarget(data->window, data->x, data->y,
X	    TARG_PLAYER|TARG_CLOAK);
X	setwatch(target->o_num);
X	return;
X    }
X
X    if ((data->detail & 0xf) == RightButton) {
X	course = getcourse(data->window, data->x, data->y);
X	me->p_desdir = course;
X	me->p_flags &= ~(PFPLOCK | PFPLLOCK);
X    }
X    else if ((data->detail & 0xf) == LeftButton) {
X	course = getcourse(data->window, data->x, data->y);
X	ntorp(course, TMOVE, data->time);
X    }
X    else if ((data->detail & 0xf) == MiddleButton) {
X	course = getcourse(data->window, data->x, data->y);
X	phaser(course);
X    }
X}
X
Xgetcourse(ww, x, y)
XWindow ww;
Xint x, y;
X{
X    if (ww == mapw) {
X	int	me_x, me_y;
X
X	me_x = me->p_x * WINSIDE / GWIDTH;
X	me_y = me->p_y * WINSIDE / GWIDTH;
X	return((unsigned char) (atan2((double) (x - me_x),
X	    (double) (me_y - y)) / 3.14159 * 128.));
X    }
X    else
X	return((unsigned char) (atan2((double) (x - WINSIDE/2),
X	    (double) (WINSIDE/2 - y))
X		/ 3.14159 * 128.));
X}
X
XinputIgnored()
X{
X	if (watch)
X	    return(0);
X	if (me->p_status != PALIVE)
X	    return (1);
X	if (me->p_flags & PFWAR) {
X	    warning("Battle computers being re-programmed");
X	    return (1);
X	}
X	return (0);
X}
X
Xsetwatch(pno)
Xint pno;
X{
X    me = &players[pno];
X    myship = &me->p_ship;
X    mystats = &me->p_stats;
X    lastm = mctl->mc_current;
X    redrawall = 1;
X    if (showStats) {
X	closeStats(statwin);
X	statwin = openStats(me);
X    }
X}
END_OF_input.c
if test 10383 -ne `wc -c <input.c`; then
    echo shar: \"input.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f newwin.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"newwin.c\"
else
echo shar: Extracting \"newwin.c\" \(16570 characters\)
sed "s/^X//" >newwin.c <<'END_OF_newwin.c'
X/*
X
X	Copyright (c) 1986 	Chris Guthrie
X
XPermission to use, copy, modify, and distribute this
Xsoftware and its documentation for any purpose and without
Xfee is hereby granted, provided that the above copyright
Xnotice appear in all copies and that both that copyright
Xnotice and this permission notice appear in supporting
Xdocumentation.  No representations are made about the
Xsuitability of this software for any purpose.  It is
Xprovided "as is" without express or implied warranty.
X
X*/
X
X#include <X/Xlib.h>
X#include <stdio.h>
X#include <math.h>
X#include <signal.h>
X#include <sys/types.h>
X#ifdef hpux
X#include <time.h>
X#else hpux
X#include <sys/time.h>
X#endif hpux
X#include "defs.h"
X#include "struct.h"
X#include "data.h"
X#include "bitmaps.h"
X
X#define SIZEOF(a)	(sizeof (a) / sizeof (*(a)))
X
X#define WINSIDE		500
X#define BOXSIDE		(WINSIDE / 5)
X#define BORDER		4
X#define TILESIDE	16
X#define MESSAGESIZE	20
X#define STATSIZE	(MESSAGESIZE * 2 + BORDER)
X#define YOFF		100
X
Xstatic FontInfo	*bigFont;
X    
Xnewwin(hostmon, progname)
Xchar *hostmon, *progname;
X{
X
X    if ((display = XOpenDisplay(hostmon)) == NULL) {
X	perror(hostmon);
X	exit(1);
X    }
X    getResources(progname);
X
X    savebitmaps();
X
X    baseWin = XCreateWindow(RootWindow, 0, YOFF, WINSIDE * 2 + 1 * BORDER,
X	WINSIDE + 2 * BORDER + 2 * MESSAGESIZE, BORDER, gTile, backTile);
X    iconWin = XCreateWindow(RootWindow, 0, 0, icon_width, icon_height,
X	BORDER, gTile, backTile);
X    XSetIconWindow(baseWin, iconWin);
X    w = XCreateWindow(baseWin, -BORDER, -BORDER, WINSIDE, WINSIDE, 
X	BORDER, foreTile, backTile);
X    mapw = XCreateWindow(baseWin, WINSIDE, -BORDER, WINSIDE,
X	WINSIDE, BORDER, foreTile, backTile);
X    tstatw = XCreateWindow(baseWin, -BORDER, WINSIDE, WINSIDE,
X	STATSIZE, BORDER, foreTile, backTile);
X    warnw = XCreateWindow(baseWin, WINSIDE, WINSIDE,
X	WINSIDE, MESSAGESIZE, BORDER, foreTile, backTile);
X    messagew = XCreateWindow(baseWin, WINSIDE,
X	WINSIDE + BORDER + MESSAGESIZE,
X	WINSIDE, MESSAGESIZE, BORDER, foreTile, backTile);
X    planetw = XCreateWindow(w, 10, 10, 47 * dfontinfo->width,
X	(MAXPLANETS + 3) * dfontinfo->height, 2, foreTile, backTile);
X    playerw = XCreateWindow(w, 10, 10, 66 * dfontinfo->width,
X	(MAXPLAYER + 3) * dfontinfo->height, 2, foreTile, backTile);
X    helpWin = XCreateWindow(RootWindow,
X	0, YOFF + WINSIDE + 2 * BORDER + 2 * MESSAGESIZE,
X	WINSIDE * 2 + 1 * BORDER, 10 * dfontinfo->height,
X	BORDER, foreTile, backTile);
X    XDefineCursor(baseWin, crosshair);
X    XDefineCursor(iconWin, crosshair);
X
X/* These windows will be used for setting one's warlike stats */
X
X#define WARHEIGHT (dfontinfo->height * 2)
X#define WARWIDTH (dfontinfo->width * 20)
X#define WARBORDER 2
X    war = XCreateWindow(baseWin, WINSIDE+ 10, -BORDER + 10, WARWIDTH,
X	WARHEIGHT * 6, WARBORDER, foreTile, backTile);
X    warf = XCreateWindow(war, 0, 0 * WARHEIGHT, WARWIDTH,
X	 WARHEIGHT, WARBORDER, foreTile, backTile);
X    warr = XCreateWindow(war, 0, 1 * WARHEIGHT, WARWIDTH,
X	 WARHEIGHT, WARBORDER, foreTile, backTile);
X    wark = XCreateWindow(war, 0, 2 * WARHEIGHT, WARWIDTH,
X	 WARHEIGHT, WARBORDER, foreTile, backTile);
X    waro = XCreateWindow(war, 0, 3 * WARHEIGHT, WARWIDTH,
X	 WARHEIGHT, WARBORDER, foreTile, backTile);
X    wargo = XCreateWindow(war, 0, 4 * WARHEIGHT, WARWIDTH,
X	 WARHEIGHT, WARBORDER, foreTile, backTile);
X    warno = XCreateWindow(war, 0, 5 * WARHEIGHT, WARWIDTH,
X	 WARHEIGHT, WARBORDER, foreTile, backTile);
X
X    XMapWindow(warf);
X    XMapWindow(warr);
X    XMapWindow(wark);
X    XMapWindow(waro);
X    XMapWindow(wargo);
X    XMapWindow(warno);
X}
X
X/*
X * this is separate from newwin.  It should; be called *after*
X * openmem.  If not, expose events will be eaten by the forked
X * process (daemon).
X */
XmapAll()
X{
X    initinput();
X    XMapWindow(mapw);
X    XMapWindow(tstatw);
X    XMapWindow(warnw);
X    XMapWindow(messagew);
X    XMapWindow(w);
X    XMapWindow(baseWin);
X}
X
Xsavebitmaps()
X{
X    register int i;
X    crosshair = XCreateCursor(crossw, crossh, crossbits, crossmask_bits, 8, 8,
X	myColor, backColor, GXcopy);
X    for (i = 0; i < VIEWS; i++) {
X	fedview[i] = XStoreBitmap(ship_width, ship_height, fed_bits[i]);
X	romview[i] = XStoreBitmap(ship_width, ship_height, rom_bits[i]);
X	kliview[i] = XStoreBitmap(ship_width, ship_height, kli_bits[i]);
X	oriview[i] = XStoreBitmap(ship_width, ship_height, ori_bits[i]);
X    }
X    cloud = XStoreBitmap(cloud_width, cloud_height, cloud_bits);
X    etorp = XStoreBitmap(etorp_width, etorp_height, etorp_bits);
X    mtorp = XStoreBitmap(mtorp_width, mtorp_height, mtorp_bits);
X    bplanet = XStoreBitmap(planet_width, planet_height, planet_bits);
X    /*
X    e_bplanetPix = XMakePixmap(bplanet, enemyColor, backColor);
X    a_bplanetPix = XMakePixmap(bplanet, allyColor, backColor);
X    */
X    mbplanet = XStoreBitmap(mplanet_width, mplanet_height, mplanet_bits);
X    /*
X    e_mbplanetPix = XMakePixmap(mbplanet, enemyColor, backColor);
X    a_mbplanetPix = XMakePixmap(mbplanet, allyColor, backColor);
X    */
X    for (i = 0; i < EX_FRAMES; i++) {
X	expview[i] = XStoreBitmap(ex_width, ex_height, ex_bits[i]);
X    }
X    shield = XStoreBitmap(shield_width, shield_height, shield_bits);
X}
X
X/* This routine throws up an entry window for the player. */
X
Xentrywindow() 
X{
X    int team;
X    long	startTime;
X    Window fwin, rwin, kwin, owin, qwin;
X    XEvent event;
X
X    /* The following allows quick choosing of teams */
X    if ((me->p_team & FED) && !mustexit) {
X	fwin = XCreateWindow(w, 0 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[1]), backTile);
X	XSelectInput(fwin, KeyPressed|ButtonPressed|ButtonReleased|
X	    ExposeRegion);
X	XMapWindow(fwin);
X    }
X    else {
X	fwin = XCreateWindow(w, 0 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[1]), stippleTile);
X	XSelectInput(fwin, ExposeRegion);
X	XMapWindow(fwin);
X    }
X    if ((me->p_team & ROM) && !mustexit) {
X	rwin = XCreateWindow(w, 1 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[2]), backTile);
X	XSelectInput(rwin, KeyPressed|ButtonPressed|ButtonReleased|
X	    ExposeRegion);
X	XMapWindow(rwin);
X    }
X    else {
X	rwin = XCreateWindow(w, 1 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[2]), stippleTile);
X	XSelectInput(rwin, ExposeRegion);
X	XMapWindow(rwin);
X    }
X    if ((me->p_team & KLI) && !mustexit) {
X	kwin = XCreateWindow(w, 2 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[3]), backTile);
X	XSelectInput(kwin, KeyPressed|ButtonPressed|ButtonReleased|
X	    ExposeRegion);
X	XMapWindow(kwin);
X    }
X    else {
X	kwin = XCreateWindow(w, 2 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[3]), stippleTile);
X	XSelectInput(kwin, ExposeRegion);
X	XMapWindow(kwin);
X    }
X    if ((me->p_team & ORI) && !mustexit) {
X	owin = XCreateWindow(w, 3 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1,
X	    XMakeTile(shipCol[4]), backTile);
X	XSelectInput(owin, KeyPressed|ButtonPressed|ButtonReleased|
X	    ExposeRegion);
X	XMapWindow(owin);
X    }
X    else {
X	owin = XCreateWindow(w, 3 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1, 
X	    XMakeTile(shipCol[4]), stippleTile);
X	XSelectInput(owin, ExposeRegion);
X	XMapWindow(owin);
X    }
X    qwin = XCreateWindow(w, 4 * BOXSIDE, 400, BOXSIDE, BOXSIDE, 1,
X	XMakeTile(textColor), backTile);
X    XSelectInput(qwin, KeyPressed|ButtonPressed|ExposeRegion);
X    XMapWindow(qwin);
X
X    team = -1;
X    startTime = time(0);
X    makeClock(qwin);
X    do {
X	    me->p_ghostbuster = 0;
X	    while (!XPending()) {
X		int		mask, elapsed;
X		struct timeval	tv;
X
X		me->p_ghostbuster = 0;
X		tv.tv_sec = 1;
X		tv.tv_usec = 0;
X		mask = 1 << dpyno();
X		select(dpyno() + 1, &mask, 0, 0, &tv);
X		elapsed = time(0) - startTime;
X		if (elapsed > AUTOQUIT) {
X		    printf("Auto-Quit.\n");
X		    team = 4;
X		    break;
X		}
X		showTimeLeft(elapsed, AUTOQUIT);
X		redrawFed(fwin);
X		redrawRom(rwin);
X		redrawKli(kwin);
X		redrawOri(owin);
X	    }
X	    if (team == 4)
X		break;
X
X	    XNextEvent(&event);
X	    switch ((int) event.type) {
X		case KeyPressed:
X		case ButtonPressed:
X		    if (event.window == fwin)
X			team = 0;
X		    else if (event.window == rwin)
X			team = 1;
X		    else if (event.window == kwin)
X			team = 2;
X		    else if (event.window == owin)
X			team = 3;
X		    else if (event.window == qwin)
X			team = 4;
X		    break;
X		case ExposeRegion:
X		case ExposeWindow:
X		    if (event.window == fwin)
X			redrawFed(fwin);
X		    else if (event.window == rwin)
X			redrawRom(rwin);
X		    else if (event.window == kwin)
X			redrawKli(kwin);
X		    else if (event.window == owin)
X			redrawOri(owin);
X		    else if (event.window == qwin)
X			redrawQuit(qwin);
X		    else if (event.window == tstatw)
X			redrawTstats();
X		    else if (event.window == iconWin)
X  			drawIcon();
X		    else if (event.window == w)
X			showMotd();
X		    else if (event.window == helpWin)
X			fillhelp();
X		    break;
X	    }
X    } while (team < 0);
X    destroyClock();
X
X    if (team == 4)
X	team = -1;
X				
X    XDestroyWindow(fwin);
X    XDestroyWindow(rwin);
X    XDestroyWindow(kwin);
X    XDestroyWindow(owin);
X    XDestroyWindow(qwin);
X    return(team);
X}
X
XnumShips(owner)
X{
X	int		i, num = 0;
X	struct player	*p;
X
X	for (i = 0, p = players; i < MAXPLAYER; i++, p++)
X		if (p->p_status == PALIVE && p->p_team == owner)
X			num++;
X	return (num);
X}
X
Xstatic char	*AUTHOR[] = {
X    "",
X    "---  XTREK Release Version 4.0 ---",
X    "",
X    "By Chris Guthrie (chris@ic.berkeley.edu)",
X    "And Ed James (edjames@ic.berkeley.edu)"
X};
X
XshowMotd()
X{
X    char buf[BUFSIZ];
X    FILE *motd, *fopen();
X    int	i, length, top, center;
X
X    /* Author Gratification */
X    XClear(w);
X    for (i = 0; i < SIZEOF(AUTHOR); i++) {
X	length = strlen(AUTHOR[i]);
X	center = WINSIDE / 2 - (length * dfontinfo->width) / 2;
X	XText(w, center, i * dfontinfo->height, AUTHOR[i], 
X	    length, dfont, textColor, backColor);
X    }
X    top = SIZEOF(AUTHOR) + 2;
X
X    /* the following will print a motd */
X    if ((motd = fopen(MOTD, "r")) != NULL) {
X	for (i = top; fgets(buf, sizeof (buf), motd) != NULL; i++) {
X	    length = strlen(buf);
X	    buf[length-1] = NULL;
X	    if (length > 80)
X		length = 80;
X	    XText(w, 20, i * dfontinfo->height, buf, length, dfont,
X		textColor, backColor);
X	}
X	(void) fclose(motd);
X    }
X}
X
XgetResources(prog)
X	char	*prog;
X{
X    getColorDefs(prog);
X    getFonts(prog);
X    getTiles(prog);
X    initStats(prog);
X
X    showShields = booleanDefault(prog, "showshields");
X    showStats = booleanDefault(prog, "showstats");
X}
X
Xstatic short	solid[TILESIDE] = {
X	0xffff, 0xffff, 0xffff, 0xffff,
X	0xffff, 0xffff, 0xffff, 0xffff,
X	0xffff, 0xffff, 0xffff, 0xffff,
X	0xffff, 0xffff, 0xffff, 0xffff,
X};
Xstatic short	gray[TILESIDE] = {
X	0xaaaa, 0x5555, 0xaaaa, 0x5555,
X	0xaaaa, 0x5555, 0xaaaa, 0x5555,
X	0xaaaa, 0x5555, 0xaaaa, 0x5555,
X	0xaaaa, 0x5555, 0xaaaa, 0x5555,
X};
Xstatic short	striped[TILESIDE] = {
X	0xff00, 0xff00, 0xff00, 0xff00,
X	0x0ff0, 0x0ff0, 0x0ff0, 0x0ff0,
X	0x00ff, 0x00ff, 0x00ff, 0x00ff,
X	0xf00f, 0xf00f, 0xf00f, 0xf00f,
X};
X
XgetTiles(prog)
X	char	*prog;
X{
X	short	rPatt[TILESIDE], yPatt[TILESIDE], gPatt[TILESIDE];
X	int	rSize = sizeof (rPatt);
X	int	ySize = sizeof (yPatt);
X	int	gSize = sizeof (gPatt);
X
X	backTile = XMakeTile(backColor);
X	foreTile = XMakeTile(borderColor);
X
X	if (DisplayCells() > 2) {
X		rTile = XMakeTile(rColor);
X		yTile = XMakeTile(yColor);
X		gTile = XMakeTile(gColor);
X	} else {
X		if (arrayDefault(prog, "RalertPattern", &rSize, rPatt) < 0) {
X			rSize = TILESIDE;
X			bcopy(striped, rPatt, sizeof (rPatt));
X		}
X		if (arrayDefault(prog, "YalertPattern", &ySize, yPatt) < 0) {
X			ySize = TILESIDE;
X			bcopy(gray, yPatt, sizeof (yPatt));
X		}
X		if (arrayDefault(prog, "GalertPattern", &gSize, gPatt) < 0) {
X			gSize = TILESIDE;
X			bcopy(solid, gPatt, sizeof (gPatt));
X		}
X
X		rTile = XMakePixmap(XStoreBitmap(rSize, rSize, rPatt), 
X			rColor, backColor);
X		yTile = XMakePixmap(XStoreBitmap(ySize, ySize, yPatt), 
X			yColor, backColor);
X		gTile = XMakePixmap(XStoreBitmap(gSize, gSize, gPatt), 
X			gColor, backColor);
X	}
X	stippleTile = XMakePixmap(XStoreBitmap(stipple_width,
X		stipple_height, stipple_bits), 
X		textColor, backColor);
X}
X
XgetFonts(prog)
X	char	*prog;
X{
X    char	*font;
X
X    if ((font = XGetDefault(prog, "font")) == NULL)
X	font = "6x10";
X    if ((dfontinfo = XOpenFont(font)) == NULL) {
X	perror(font);
X	exit(1);
X    }
X
X    if ((font = XGetDefault(prog, "boldfont")) == NULL)
X	font = "6x10b";
X    if ((bfontinfo = XOpenFont(font)) == NULL)
X	bfontinfo = dfontinfo;
X
X    if ((font = XGetDefault(prog, "italicFont")) == NULL)
X	font = "6x10i";
X    if ((ifontinfo = XOpenFont(font)) == NULL)
X	ifontinfo = dfontinfo;
X
X    if ((font = XGetDefault(prog, "bigFont")) == NULL)
X	font = "sbdr40sx";
X    if ((bigFont = XOpenFont(font)) == NULL)
X	bigFont = dfontinfo;
X
X    dfont = dfontinfo->id;
X    bfont = bfontinfo->id;
X    ifont = ifontinfo->id;
X}
X
XredrawFed(fwin)
X	Window fwin;
X{
X    char buf[BUFSIZ];
X
X    XClear(fwin);
X    XText(fwin, 5, 5, "Federation", 10, dfont, shipCol[1], backColor);
X    (void) sprintf(buf, "%d", numShips(FED));
X    XTextMask(fwin, 5, 50, buf, strlen(buf), bigFont->id, shipCol[1]);
X}
X
XredrawRom(rwin)
X	Window rwin;
X{
X    char buf[BUFSIZ];
X
X    XClear(rwin);
X    XText(rwin, 5, 5, "Romulan", 7, dfont, shipCol[2], backColor);
X    (void) sprintf(buf, "%d", numShips(ROM));
X    XTextMask(rwin, 5, 50, buf, strlen(buf), bigFont->id, shipCol[1]);
X}
X
XredrawKli(kwin)
X	Window kwin;
X{
X    char buf[BUFSIZ];
X
X    XClear(kwin);
X    XText(kwin, 5, 5, "Klingon", 7, dfont, shipCol[3], backColor);
X    (void) sprintf(buf, "%d", numShips(KLI));
X    XTextMask(kwin, 5, 50, buf, strlen(buf), bigFont->id, shipCol[1]);
X}
X
XredrawOri(owin)
X	Window owin;
X{
X    char buf[BUFSIZ];
X
X    XClear(owin);
X    XText(owin, 5, 5, "Orion", 5, dfont, shipCol[4], backColor);
X    (void) sprintf(buf, "%d", numShips(ORI));
X    XTextMask(owin, 5, 50, buf, strlen(buf), bigFont->id, shipCol[1]);
X}
X
XredrawQuit(qwin)
X	Window qwin;
X{
X    XText(qwin, 5, 5, "Quit xtrek", 10, dfont, textColor, backColor);
X}
X
Xchar *help_message[] = {
X    "0-9  Set speed",
X    "k    Set course",
X    "p    Fire phaser",
X    "t    Launch torp",
X    "d    detonate other torps",
X    "D    detonate your torps",
X    "L    List players",
X    "P    List planets",
X    "S    (Un)Map status window",
X    "M    Turn on/off map window updating",
X    "+    Put up screens",
X    "-    Put down screens",
X    "u    Toggle screens",
X    "i    Get info on player/planet",
X    "b    Bomb planet",
X    "z    Beam up armies",
X    "x    Beam down armies",
X    "R    Enter repair mode",
X    "o    orbit planet",
X    "Q    Quit",
X    "?    Review messages",
X    "c    Toggle cloak mode",
X    "C    Coup a planet",
X    "l    Lock on to player/planet",
X    "@    (Dis)Allow copilots",
X    "h    (Un)Map this window",
X    "w    (Un)Map war window",
X    "*    Send in practice robot",
X    0,
X};
X
X#define MAXHELP 40
X
Xfillhelp()
X{
X    register int i = 0, row, column;
X
X    for (column = 0; column < 4; column++) {
X	for (row = 1; row < 9; row++) {
X	    if (help_message[i] == 0)
X		break;
X	    else {
X		XText(helpWin, dfontinfo->width * (MAXHELP * column + 1),
X		    dfontinfo->height * row, help_message[i],
X		    strlen(help_message[i]), dfont, textColor, backColor);
X		i++;
X	    }
X	}
X	if (help_message[i] == 0)
X	    break;
X    }
X}
X
XdrawIcon()
X{
X    XBitmapBitsPut(iconWin, 0, 0, icon_width, icon_height, icon_bits, 
X	WhitePixel, BlackPixel, 0, GXcopy, AllPlanes);
X}
X
Xstatic Window	clock;
X
X#define CLOCK_WID	(BOXSIDE * 9 / 10)
X#define CLOCK_HEI	(BOXSIDE * 2 / 3)
X#define CLOCK_BDR	0
X#define CLOCK_X		(BOXSIDE / 2 - CLOCK_WID / 2)
X#define CLOCK_Y		(BOXSIDE / 2 - CLOCK_HEI / 2)
X
XmakeClock(w)
X	Window	w;
X{
X	clock = XCreateWindow(w, CLOCK_X, CLOCK_Y, CLOCK_WID, CLOCK_HEI,
X		CLOCK_BDR, foreTile, backTile);
X	XMapWindow(clock);
X}
X
XdestroyClock()
X{
X	XDestroyWindow(clock);
X}
X
X#define PI		3.141592654
X#include "clock.bitmap"
X
XshowTimeLeft(time, max)
X{
X	char	buf[BUFSIZ], *cp;
X	int	cx, cy, ex, ey, tx, ty;
X
X	XClear(clock);
X
X	cx = CLOCK_WID / 2;
X	cy = (CLOCK_HEI - dfontinfo->height) / 2;
X	ex = cx - clock_width / 2;
X	ey = cy - clock_height / 2;
X	XBitmapBitsPut(clock, ex, ey, clock_width, clock_height, clock_bits, 
X	    textColor, backColor, 0, GXcopy, AllPlanes);
X
X	ex = cx - clock_width * sin(2 * PI * time / max) / 2;
X	ey = cy - clock_height * cos(2 * PI * time / max) / 2;
X	XLine(clock, cx, cy, ex, ey, 1, 1, textColor, GXcopy, AllPlanes);
X
X	sprintf(buf, "%d", max - time);
X	tx = cx - dfontinfo->width * strlen(buf) / 2;
X	ty = cy - dfontinfo->height / 2;
X	XText(clock, tx, ty, buf, strlen(buf), dfont, textColor, backColor);
X
X	cp = "Auto Quit";
X	tx = cx - dfontinfo->width * strlen(cp) / 2;
X	ty = CLOCK_HEI - dfontinfo->height;
X	XText(clock, tx, ty, cp, strlen(cp), dfont, textColor, backColor);
X}
END_OF_newwin.c
if test 16570 -ne `wc -c <newwin.c`; then
    echo shar: \"newwin.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f redraw.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"redraw.c\"
else
echo shar: Extracting \"redraw.c\" \(21165 characters\)
sed "s/^X//" >redraw.c <<'END_OF_redraw.c'
X
X/*
X
X	Copyright (c) 1986 	Chris Guthrie
X
XPermission to use, copy, modify, and distribute this
Xsoftware and its documentation for any purpose and without
Xfee is hereby granted, provided that the above copyright
Xnotice appear in all copies and that both that copyright
Xnotice and this permission notice appear in supporting
Xdocumentation.  No representations are made about the
Xsuitability of this software for any purpose.  It is
Xprovided "as is" without express or implied warranty.
X
X*/
X
X#include <X/Xlib.h>
X#include <stdio.h>
X#include <signal.h>
X#include <math.h>
X#include "defs.h"
X#include "struct.h"
X#include "data.h"
X#include "bitmaps.h"
X
X#define WINSIDE 500
X
Xstatic char *shipnos = "0123456789abcdef";
X
Xstatic int clearzone[4][(MAXTORP + 1) * MAXPLAYER + MAXPLANETS];
Xstatic int clearcount;
Xstatic int clearline[4][MAXPLAYER];
Xstatic int clearlcount;
Xstatic int mclearzone[4][MAXPLAYER + MAXPLANETS];	/* For map window */
Xstatic int mclearcount;
X
Xstatic short nplayers;
X
Xintrupt()
X{
X    if (((me->p_status == PDEAD) || (me->p_status == POUTFIT))
X	&& (me->p_ntorp <= 0)) {
X	if (copilot)
X	    exit(0);
X	else if (!watch)
X	    death();
X    }
X
X    if (! (copilot || watch))
X	udcounter++;
X    auto_features();
X    redraw();
X}
X
Xredraw()
X{
X
X    /* erase warning line if necessary */
X    if ((warntimer <= udcounter) && (warncount > 0)) {
X	XPixSet(warnw, 5, 5, dfontinfo->width * warncount, dfontinfo->height,
X	    backColor);
X	warncount = 0;
X    }
X
X    while (clearcount) {
X	clearcount--;
X	XPixSet(w, clearzone[0][clearcount], clearzone[1][clearcount],
X	    clearzone[2][clearcount], clearzone[3][clearcount],
X	    backColor);
X    }
X    while (clearlcount) {
X	clearlcount--;
X	XLine(w, clearline[0][clearlcount], clearline[1][clearlcount],
X	    clearline[2][clearlcount], clearline[3][clearlcount],
X	    1, 1, backColor, GXcopy, AllPlanes);
X    }
X
X    if ((mapmode) && (udcounter % ((nplayers == 0) ? 1 : nplayers) == 0))
X	map();
X
X    /* Display a new message every MESSTIME/10 seconds */
X    if (udcounter % MESSTIME == 0)
X	dmessage();
X
X    local();	/* redraw local window */
X
X    stline();
X
X    if (showStats)
X	updateStats(statwin);
X
X}
X
Xlocal()
X{
X    register int h, i;
X    register struct player *j;
X    register struct torp *k;
X    register struct planet *l;
X    register struct phaser *php;
X
X    int dx, dy;
X    int view;
X
X    /* Draw Planets */
X    view = SCALE * WINSIDE / 2;
X    for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
X	dx = l->pl_x - me->p_x;
X	dy = l->pl_y - me->p_y;
X	if (dx > view || dx < -view || dy > view || dy < -view)
X	    continue;
X	dx = dx / SCALE + WINSIDE / 2;
X	dy = dy / SCALE + WINSIDE / 2;
X	XPixFill(w, dx - (planet_width/2), dy - (planet_height/2),
X	    planet_width, planet_height,
X	    planetColor(l), bplanet, GXcopy, AllPlanes);
X	if (namemode) {
X	    XText(w, dx - (planet_width/2), dy + (planet_height/2),
X		l->pl_name, l->pl_namelen, planetFont(l),
X		planetColor(l), backColor);
X	    clearzone[0][clearcount] = dx - (planet_width/2);
X	    clearzone[1][clearcount] = dy + (planet_height/2);
X	    clearzone[2][clearcount] = dfontinfo->width * l->pl_namelen;
X	    clearzone[3][clearcount] = dfontinfo->height;
X	    clearcount++;
X	}
X	clearzone[0][clearcount] = dx - (planet_width/2);
X	clearzone[1][clearcount] = dy - (planet_height/2);
X	clearzone[2][clearcount] = planet_width;
X	clearzone[3][clearcount] = planet_height;
X	clearcount++;
X    }
X
X    /* Draw ships */
X    nplayers = 0;
X    view = SCALE * WINSIDE / 2;
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	int tx, ty;
X	if ((j->p_status != PALIVE) && (j->p_status != PEXPLODE))
X	    continue;
X	if (j->p_flags & PFCLOAK)
X	    continue;
X	nplayers++;
X	dx = j->p_x - me->p_x;
X	dy = j->p_y - me->p_y;
X	if (dx > view || dx < -view || dy > view || dy < -view)
X	    continue;
X	dx = dx / SCALE + WINSIDE / 2;
X	dy = dy / SCALE + WINSIDE / 2;
X	if (j->p_status == PALIVE) {
X	    switch (j->p_team) {
X		case FED:
X		    XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
X			ship_width, ship_height, playerColor(j),
X			fedview[rosette(j->p_dir)], GXcopy, AllPlanes);
X		    break;
X		case ROM:
X		    XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
X			ship_width, ship_height, playerColor(j),
X			romview[rosette(j->p_dir)], GXcopy, AllPlanes);
X		    break;
X		case KLI:
X		    XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
X			ship_width, ship_height, playerColor(j),
X			kliview[rosette(j->p_dir)], GXcopy, AllPlanes);
X		    break;
X		case ORI:
X		    XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
X			ship_width, ship_height, playerColor(j),
X			oriview[rosette(j->p_dir)], GXcopy, AllPlanes);
X		    break;
X	    }
X	    XText(w, dx + (ship_width/2), dy - (ship_height/2),
X		shipnos + j->p_no, 1, shipFont(j), playerColor(j), backColor);
X	       
X	    if (showShields && j->p_flags & PFSHIELD)
X		XPixFill(w, dx - (shield_width/2), dy - (shield_height/2),
X		    shield_width, shield_height, playerColor(j),
X		    shield, GXcopy, AllPlanes);
X
X	    clearzone[0][clearcount] = dx + (ship_width/2);
X	    clearzone[1][clearcount] = dy - (ship_height/2);
X	    clearzone[2][clearcount] = dfontinfo->width;
X	    clearzone[3][clearcount] = dfontinfo->height;
X	    clearcount++;
X	    clearzone[0][clearcount] = dx - (shield_width/2);
X	    clearzone[1][clearcount] = dy - (shield_height/2);
X	    clearzone[2][clearcount] = shield_width;
X	    clearzone[3][clearcount] = shield_height;
X	    clearcount++;
X	}
X	else if (j->p_status == PEXPLODE) {
X	    XPixFill(w, dx - (ex_width/2), dy - (ex_height/2),
X		ex_width, ex_height, playerColor(j),
X		expview[(10 - j->p_explode)/2], GXcopy, AllPlanes);
X	    clearzone[0][clearcount] = dx - (ex_width/2);
X	    clearzone[1][clearcount] = dy - (ex_height/2);
X	    clearzone[2][clearcount] = ex_width;
X	    clearzone[3][clearcount] = ex_height;
X	    clearcount++;
X	}
X	/* Now draw his phaser (if it exists) */
X	php = &phasers[j->p_no];
X	if (php->ph_status != PHFREE) {
X	    if (php->ph_status == PHMISS) {
X		/* Here I will have to compute end coordinate */
X		tx = j->p_x + PHASEDIST * Cos[php->ph_dir];
X		ty = j->p_y + PHASEDIST * Sin[php->ph_dir];
X		tx = (tx - me->p_x) / SCALE + WINSIDE / 2;
X		ty = (ty - me->p_y) / SCALE + WINSIDE / 2;
X		XLine(w, dx, dy, tx, ty, 1, 1, phaserColor(php),
X			GXcopy, AllPlanes);
X	    }
X	    else { /* Start point is dx, dy */
X		tx = (players[php->ph_target].p_x - me->p_x) /
X		    SCALE + WINSIDE / 2;
X		ty = (players[php->ph_target].p_y - me->p_y) /
X		    SCALE + WINSIDE / 2;
X		XLine(w, dx, dy, tx, ty, 1, 1, phaserColor(php),
X			GXcopy, AllPlanes);
X	    }
X	    clearline[0][clearlcount] = dx;
X	    clearline[1][clearlcount] = dy;
X	    clearline[2][clearlcount] = tx;
X	    clearline[3][clearlcount] = ty;
X	    clearlcount++;
X	}
X    }
X    /* Draw torps */
X    view = SCALE * WINSIDE / 2;
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	if (!j->p_ntorp)
X	    continue;
X	for (h = 0, k = &torps[MAXTORP * i + h]; h < MAXTORP; h++, k++) {
X	    if (!k->t_status)
X		continue;
X	    dx = k->t_x - me->p_x;
X	    dy = k->t_y - me->p_y;
X	    if (dx > view || dx < -view || dy > view || dy < -view)
X		continue;
X	    dx = dx / SCALE + WINSIDE / 2;
X	    dy = dy / SCALE + WINSIDE / 2;
X	    if (k->t_status == TEXPLODE) {
X		XPixFill(w, dx - (cloud_width/2), dy - (cloud_height/2),
X		    cloud_width, cloud_height, torpColor(k),
X		    cloud, GXcopy, AllPlanes);
X		clearzone[0][clearcount] = dx - (cloud_width/2);
X		clearzone[1][clearcount] = dy - (cloud_height/2);
X		clearzone[2][clearcount] = cloud_width;
X		clearzone[3][clearcount] = cloud_height;
X		clearcount++;
X	    }
X	    else if (k->t_owner != me->p_no && ((k->t_war & me->p_team) ||
X		      (k->t_team & (me->p_hostile | me->p_swar))))
X	    {
X		XPixFill(w, dx - (etorp_width/2), dy - (etorp_height/2),
X		    etorp_width, etorp_height, torpColor(k),
X		    etorp, GXcopy, AllPlanes);
X		clearzone[0][clearcount] = dx - (etorp_width/2);
X		clearzone[1][clearcount] = dy - (etorp_height/2);
X		clearzone[2][clearcount] = etorp_width;
X		clearzone[3][clearcount] = etorp_height;
X		clearcount++;
X	    }
X	    else {
X		XPixFill(w, dx - (mtorp_width/2), dy - (mtorp_height/2),
X		    mtorp_width, mtorp_height, torpColor(k),
X		    mtorp, GXcopy, AllPlanes);
X		clearzone[0][clearcount] = dx - (mtorp_width/2);
X		clearzone[1][clearcount] = dy - (mtorp_height/2);
X		clearzone[2][clearcount] = mtorp_width;
X		clearzone[3][clearcount] = mtorp_height;
X		clearcount++;
X	    }
X	}
X    }
X    /* Draw Edges */
X    if (me->p_x < (WINSIDE / 2) * SCALE) {
X	int	sy, ey;
X
X	dx = (WINSIDE / 2) - (me->p_x) / SCALE;
X	sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE;
X	ey = (WINSIDE / 2) + (GWIDTH - me->p_y) / SCALE;
X	if (sy < 0) sy = 0;
X	if (ey > WINSIDE - 1) ey = WINSIDE - 1;
X	XLine(w, dx, sy, dx, ey, 1, 1, warningColor, GXcopy, AllPlanes);
X	clearline[0][clearlcount] = dx;
X	clearline[1][clearlcount] = sy;
X	clearline[2][clearlcount] = dx;
X	clearline[3][clearlcount] = ey;
X	clearlcount++;
X    }
X    if ((GWIDTH - me->p_x) < (WINSIDE / 2) * SCALE) {
X	int	sy, ey;
X
X	dx = (WINSIDE / 2) + (GWIDTH - me->p_x) / SCALE;
X	sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE;
X	ey = (WINSIDE / 2) + (GWIDTH - me->p_y) / SCALE;
X	if (sy < 0) sy = 0;
X	if (ey > WINSIDE - 1) ey = WINSIDE - 1;
X	XLine(w, dx, sy, dx, ey, 1, 1, warningColor, GXcopy, AllPlanes);
X	clearline[0][clearlcount] = dx;
X	clearline[1][clearlcount] = sy;
X	clearline[2][clearlcount] = dx;
X	clearline[3][clearlcount] = ey;
X	clearlcount++;
X    }
X    if (me->p_y < (WINSIDE / 2) * SCALE) {
X	int	sx, ex;
X
X	dy = (WINSIDE / 2) - (me->p_y) / SCALE;
X	sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE;
X	ex = (WINSIDE / 2) + (GWIDTH - me->p_x) / SCALE;
X	if (sx < 0) sx = 0;
X	if (ex > WINSIDE - 1) ex = WINSIDE - 1;
X	XLine(w, sx, dy, ex, dy, 1, 1, warningColor, GXcopy, AllPlanes);
X	clearline[0][clearlcount] = sx;
X	clearline[1][clearlcount] = dy;
X	clearline[2][clearlcount] = ex;
X	clearline[3][clearlcount] = dy;
X	clearlcount++;
X    }
X    if ((GWIDTH - me->p_y) < (WINSIDE / 2) * SCALE) {
X	int	sx, ex;
X
X	dy = (WINSIDE / 2) + (GWIDTH - me->p_y) / SCALE;
X	sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE;
X	ex = (WINSIDE / 2) + (GWIDTH - me->p_x) / SCALE;
X	if (sx < 0) sx = 0;
X	if (ex > WINSIDE - 1) ex = WINSIDE - 1;
X	XLine(w, sx, dy, ex, dy, 1, 1, warningColor, GXcopy, AllPlanes);
X	clearline[0][clearlcount] = sx;
X	clearline[1][clearlcount] = dy;
X	clearline[2][clearlcount] = ex;
X	clearline[3][clearlcount] = dy;
X	clearlcount++;
X    }
X
X    /* Change border color to signify alert status */
X
X    if (oldalert != (me->p_flags & (PFGREEN|PFYELLOW|PFRED))) {
X        oldalert = (me->p_flags & (PFGREEN|PFYELLOW|PFRED));
X	switch (oldalert) {
X	    case PFGREEN:
X		XChangeBorder(baseWin, gTile);
X		XChangeBorder(iconWin, gTile);
X		break;
X	    case PFYELLOW:
X		XChangeBorder(baseWin, yTile);
X		XChangeBorder(iconWin, yTile);
X		break;
X	    case PFRED:
X		XChangeBorder(baseWin, rTile);
X		XChangeBorder(iconWin, rTile);
X		break;
X	}
X    }
X}
X
Xmap()
X{
X    char buf[80];
X    register int i;
X    register struct player *j;
X    register struct planet *l;
X    int dx, dy;
X
X    while (mclearcount) {
X	mclearcount--;
X	XPixSet(mapw, mclearzone[0][mclearcount], mclearzone[1][mclearcount],
X	    mclearzone[2][mclearcount], mclearzone[3][mclearcount],
X	    backColor);
X    }
X
X    /* Draw Planets */
X    for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
X	if (!(l->pl_flags & PLREDRAW) && (!redrawall))
X	    continue;
X	dx = l->pl_x * WINSIDE / GWIDTH;
X	dy = l->pl_y * WINSIDE / GWIDTH;
X	XPixFill(mapw, dx - (mplanet_width/2), dy - (mplanet_height/2),
X	    mplanet_width, mplanet_height,
X	    planetColor(l), mbplanet, GXcopy, AllPlanes);
X	XText(mapw, dx - (mplanet_width/2), dy + (mplanet_height/2),
X	    l->pl_name, 3, planetFont(l), planetColor(l), backColor);
X
X/*
X	clearzone[0][clearcount] = dx - (mplanet_width/2);
X	clearzone[1][clearcount] = dy + (mplanet_height/2);
X	clearzone[2][clearcount] = dfontinfo->width * 3;
X	clearzone[3][clearcount] = dfontinfo->height;
X	clearcount++;
X	clearzone[0][clearcount] = dx - (mplanet_width/2);
X	clearzone[1][clearcount] = dy - (mplanet_height/2);
X	clearzone[2][clearcount] = mplanet_width;
X	clearzone[3][clearcount] = mplanet_height;
X	clearcount++;
X*/
X    }
X    redrawall = 0;
X
X    /* Draw ships */
X    nplayers = 0;
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	if (j->p_status != PALIVE)
X	    continue;
X	nplayers++;
X	dx = j->p_x * WINSIDE / GWIDTH;
X	dy = j->p_y * WINSIDE / GWIDTH;
X	if (j->p_flags & PFCLOAK) {
X	    XText(mapw, dx - dfontinfo->width, dy - dfontinfo->height/2,
X		"??", 2, dfont, unColor, backColor);
X	}
X	else {
X	    XText(mapw, dx - dfontinfo->width, dy - dfontinfo->height/2,
X		j->p_mapchars, 2, shipFont(j), playerColor(j), backColor);
X	}
X
X	mclearzone[0][mclearcount] = dx - dfontinfo->width;
X	mclearzone[1][mclearcount] = dy - dfontinfo->height/2;
X	mclearzone[2][mclearcount] = dfontinfo->width * 2;
X	mclearzone[3][mclearcount] = dfontinfo->height;
X	mclearcount++;
X    }
X}
X
Xstline()
X{
X    char buf[80];
X
X    /* Instead of one sprintf, we do all this by hand for optimization */
X
X    buf[0] = (me->p_flags & PFSHIELD ? 'S': ' ');
X    if (me->p_flags & PFGREEN)
X	buf[1] = 'G';
X    else if (me->p_flags & PFYELLOW)
X	buf[1] = 'Y';
X    else if (me->p_flags & PFRED)
X	buf[1] = 'R';
X    buf[2] = (me->p_flags & (PFPLLOCK | PFPLOCK) ? 'L': ' ');
X    buf[3] = (me->p_flags & PFREPAIR ? 'R': ' ');
X    buf[4] = (me->p_flags & PFBOMB ? 'B': ' ');
X    buf[5] = (me->p_flags & PFORBIT ? 'O': ' ');
X    buf[6] = (me->p_flags & PFCLOAK ? 'C': ' ');
X    buf[7] = (me->p_flags & PFWEP ? 'W': ' ');
X    buf[8] = (me->p_flags & PFENG ? 'E': ' ');
X    buf[9] = (me->p_flags & PFBEAMUP ? 'u': ' ');
X    buf[10] = (me->p_flags & PFBEAMDOWN ? 'd': ' ');
X    buf[11] = (me->p_flags & PFCOPILOT ? 'P' : ' ');
X    buf[12] = ' ';
X    buf[13] = ' ';
X    buf[14] = ' ';
X    buf[15] = '0' + me->p_speed;	/* speed */
X    buf[16] = ' ';
X    buf[17] = ' ';
X    buf[18] = '0' + (me->p_damage / 100);
X    if (buf[18] == '0')
X	buf[18] = ' ';
X    buf[19] = '0' + ((me->p_damage % 100) / 10);
X    if ((buf[19] == '0') && (me->p_damage < 100))
X	buf[19] = ' ';
X    buf[20] = '0' + (me->p_damage % 10);
X    buf[21] = ' ';
X    buf[22] = '0' + (me->p_shield / 100);
X    if (buf[22] == '0')
X	buf[22] = ' ';
X    buf[23] = '0' + ((me->p_shield % 100) / 10);
X    if ((buf[23] == '0') && (me->p_shield < 100))
X	buf[23] = ' ';
X    buf[24] = '0' + (me->p_shield % 10);
X    buf[25] = ' ';
X    buf[26] = ' ';
X    buf[27] = '0' + ((me->p_ntorp % 100) / 10);
X    if (buf[27] == '0')
X	buf[27] = ' ';
X    buf[28] = '0' + (me->p_ntorp % 10);
X    buf[29] = ' ';
X    buf[30] = ' ';
X    buf[31] = ' ';
X    buf[32] = ' ';
X    buf[33] = '0' + ((int) (me->p_kills / 10));
X    if (buf[33] == '0')
X	buf[33] = ' ';
X    buf[34] = '0' + (((int) me->p_kills) % 10);
X    buf[35] = '.';
X    buf[36] = '0' + (((int) (me->p_kills * 10)) % 10);
X    buf[37] = '0' + (((int) (me->p_kills * 100)) % 10);
X    buf[38] = ' ';
X    buf[39] = ' ';
X    buf[40] = '0' + ((me->p_armies % 100) / 10);
X    if (buf[40] == '0')
X	buf[40] = ' ';
X    buf[41] = '0' + (me->p_armies % 10);
X    buf[42] = ' ';
X    buf[43] = ' ';
X    buf[44] = ' ';
X    buf[45] = ' ';
X
X    buf[46] = '0' + (me->p_fuel / 10000);
X    if (buf[46] == '0')
X	buf[46] = ' ';
X    buf[47] = '0' + ((me->p_fuel % 10000) / 1000);
X    if ((buf[47] == '0') && (me->p_fuel < 10000))
X	buf[47] = ' ';
X    buf[48] = '0' + ((me->p_fuel % 1000) / 100);
X    if ((buf[48] == '0') && (me->p_fuel < 1000))
X	buf[48] = ' ';
X    buf[49] = '0' + ((me->p_fuel % 100) / 10);
X    if ((buf[49] == '0') && (me->p_fuel < 100))
X	buf[49] = ' ';
X    buf[50] = '0' + (me->p_fuel % 10);
X    buf[51] = ' ';
X    buf[52] = ' ';
X    buf[53] = ' ';
X
X    buf[54] = '0' + ((me->p_wtemp / 10) / 100);
X    if (buf[54] == '0')
X	buf[54] = ' ';
X    buf[55] = '0' + (((me->p_wtemp / 10) % 100) / 10);
X    if ((buf[55] == '0') && (me->p_wtemp < 1000))
X	buf[55] = ' ';
X    buf[56] = '0' + ((me->p_wtemp / 10) % 10);
X
X    buf[57] = ' ';
X    buf[58] = ' ';
X    buf[59] = ' ';
X
X    buf[60] = '0' + ((me->p_etemp / 10) / 100);
X    if (buf[60] == '0')
X	buf[60] = ' ';
X    buf[61] = '0' + (((me->p_etemp / 10) % 100) / 10);
X    if ((buf[61] == '0') && (me->p_etemp < 1000))
X	buf[61] = ' ';
X    buf[62] = '0' + ((me->p_etemp / 10) % 10);
X
X    /* Draw status line */
X    XText(tstatw, 50, 20, buf, 63, dfont, textColor, backColor);
X
X#ifdef notdef
X
X    /* This code is being left around because it is much more elegant
X    ** than that above.  However, it lacks a tremendous amount in efficiency.
X    */
X    char alertchar = '?';
X
X    if (me->p_flags & PFGREEN)
X	alertchar = 'G';
X    else if (me->p_flags & PFYELLOW)
X	alertchar = 'Y';
X    else if (me->p_flags & PFRED)
X	alertchar = 'R';
X    /* Draw status line */
X    sprintf(buf,
X"%c%c%c%c%c%c%c%c%c%c%c%c   %1d  %3d %3d  %2d    %5.2f  %2d    %5d   %3d   %3d",
X	(me->p_flags & PFSHIELD ? 'S': ' '),
X	alertchar,
X	(me->p_flags & (PFPLLOCK | PFPLOCK) ? 'L': ' '),
X	(me->p_flags & PFREPAIR ? 'R': ' '),
X	(me->p_flags & PFBOMB ? 'B': ' '),
X	(me->p_flags & PFORBIT ? 'O': ' '),
X	(me->p_flags & PFCLOAK ? 'C': ' '),
X	(me->p_flags & PFWEP ? 'W': ' '),
X	(me->p_flags & PFENG ? 'E': ' '),
X	(me->p_flags & PFBEAMUP ? 'u': ' '),
X	(me->p_flags & PFBEAMDOWN ? 'd': ' '),
X	(me->p_flags & PFCOPILOT ? 'P' : ' '),
X	me->p_speed,
X	me->p_damage,
X	me->p_shield,
X	me->p_ntorp,
X	me->p_kills,
X	me->p_armies,
X	me->p_fuel,
X	me->p_wtemp/10,
X	me->p_etemp/10);
X    XText(tstatw, 50, 20, buf, strlen(buf), dfont, textColor, backColor);
X    XFlush();
X
X#endif notdef
X}
X
X/* These are routines that need to be done on interrupts but
X   don't belong in the redraw routine and particularly don't
X   belong in the daemon. */
X
Xauto_features()
X{
X    char buf[80];
X    struct player *pl;
X    struct planet *pln;
X    unsigned char course;
X
X    if (copilot && (!(me->p_flags & PFCOPILOT))) {
X	printf("Owning player has kicked you out\n");
X	exit(0);
X    }
X    if ((!copilot) && (!watch)  && (me->p_flags & PFSELFDEST)) {
X	if ((me->p_updates >= selfdest) ||
X	    ((me->p_flags & PFGREEN) && (me->p_damage == 0)
X		&& (me->p_shield == 100))) {
X	    me->p_flags &= ~PFSELFDEST;
X	    me->p_explode = 10;
X	    me->p_whydead = KQUIT;
X	    me->p_status = PEXPLODE;
X	}
X	else {
X	    sprintf(buf, "Self Destruct in %d seconds",
X		(selfdest - me->p_updates) / 10);
X	    warning(buf);
X	}
X    }
X    /* give certain information about bombing or beaming */
X    if (me->p_flags & PFBOMB) {
X	if (planets[me->p_planet].pl_armies < 5) {
X	    sprintf(buf, "Cannot bomb %s while armies are less than 5",
X		planets[me->p_planet].pl_name);
X	    warning(buf);
X	    if (! (copilot || watch))
X		me->p_flags &= ~PFBOMB;
X	}
X	else {
X	    sprintf(buf, "Bombing %s.  %d armies left",
X		planets[me->p_planet].pl_name,
X		planets[me->p_planet].pl_armies);
X	    warning(buf);
X	}
X    }
X
X    if (me->p_flags & PFBEAMUP) {
X	if (planets[me->p_planet].pl_armies < 5) {
X	    sprintf(buf, "%s: Too few armies to beam up",
X		planets[me->p_planet].pl_name);
X	    warning(buf);
X	    if (! (copilot || watch))
X		me->p_flags &= ~PFBEAMUP;
X	}
X	else if ((me->p_armies == (int) (me->p_kills * 2)) ||
X	    (me->p_armies == myship->s_maxarmies)) {
X		sprintf(buf, "No more room on board for armies");
X	    warning(buf);
X	    if (! (copilot || watch))
X		me->p_flags &= ~PFBEAMUP;
X	}
X	else {
X	    sprintf(buf, "Beaming up.  (%d/%d)", me->p_armies,
X		((me->p_kills * 2) > myship->s_maxarmies) ?
X		    myship->s_maxarmies : (int) (me->p_kills * 2));
X	    warning(buf);
X	}
X    }
X    if (me->p_flags & PFBEAMDOWN) {
X	if (me->p_armies == 0) {
X	    sprintf(buf, "No more armies to beam down to %s.",
X		planets[me->p_planet].pl_name);
X	    warning(buf);
X	    if (! (copilot || watch))
X		me->p_flags &= ~PFBEAMDOWN;
X	}
X	else {
X	    sprintf(buf, "Beaming down.  (%d/%d) %s has %d armies left",
X		me->p_armies,
X		((me->p_kills * 2) > myship->s_maxarmies) ?
X		    myship->s_maxarmies : (int) (me->p_kills * 2),
X		planets[me->p_planet].pl_name,
X		planets[me->p_planet].pl_armies);
X	    warning(buf);
X	}
X    }
X    if (me->p_flags & PFREPAIR) {
X	if ((me->p_damage == 0) && (me->p_shield == 100))
X	    if (! (copilot || watch))
X		me->p_flags &= ~PFREPAIR;
X    }
X    if (me->p_flags & PFPLOCK) { 	/* set course to player x */
X	pl = &players[me->p_playerl];
X	if (pl->p_status != PALIVE)
X	    me->p_flags &= ~PFPLOCK;
X	course = newcourse(pl->p_x, pl->p_y);
X	set_course(course);
X    }
X    if (me->p_flags & PFPLLOCK) { 	/* set course to planet x */
X	int dist;
X	pln = &planets[me->p_planet];
X	dist = hypot((double) (me->p_x - pln->pl_x),
X	    (double) (me->p_y - pln->pl_y));
X
X	/* This is magic.  It should be based on defines, but it slows
X	   the ship down to warp two an appropriate distance from the
X	   planet for orbit */
X
X	if (dist < (50 * ((me->p_speed * (me->p_speed+1)) + 10)))
X	    set_speed(2);
X	if ((dist < ENTORBDIST) && (me->p_speed <= 2))  {
X	    me->p_flags &= ~PFPLLOCK;
X	    orbit();
X	}
X	else {
X	    course = newcourse(pln->pl_x, pln->pl_y);
X	    set_course(course);
X	}
X    }
X}
X
Xnewcourse(x, y)
Xint x, y;
X{
X	return((unsigned char) (atan2((double) (x - me->p_x),
X	    (double) (me->p_y - y)) / 3.14159 * 128.));
X}
X
XredrawTstats()
X{
X    char	buf[BUFSIZ];
X
X    sprintf(buf, 
X	"Flags        warp dam shd torps  kills armies  fuel  wtemp etemp");
X    XText(tstatw, 50, 10, buf, strlen(buf), dfont, textColor, backColor);
X}
END_OF_redraw.c
if test 21165 -ne `wc -c <redraw.c`; then
    echo shar: \"redraw.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0