[comp.sources.x] v10i019: xtrek, Part08/11

ddickey@aspen.cray.com (Dan A. Dickey) (10/24/90)

Submitted-by: ddickey@aspen.cray.com (Dan A. Dickey)
Posting-number: Volume 10, Issue 19
Archive-name: xtrek/part08

#! /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
# If this archive is complete, you will see the following message at the end:
#		"End of archive 8 (of 11)."
#
# Contents:
#   redraw.c
#
# Wrapped by ddickey@cray.com on Thu Oct 11 11:43:57 1990
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
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\" \(28816 characters\)
sed "s/^X//" >redraw.c <<'END_OF_redraw.c'
Xstatic char sccsid[] = "@(#)redraw.c	3.1";
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 <X11/Xlib.h>
X#include <stdio.h>
X#include <signal.h>
X#include <math.h>
X#include "defs.h"
X#include "data.h"
X#include "bitmaps.h"
X
X#define min(a,b) ((a) < (b) ? (a) : (b))
X#define max(a,b) ((a) > (b) ? (a) : (b))
X
X/* NOTE: This definition depends on MAXPLAYERS! */
Xstatic char *shipnos = "0123456789abcdef";
X
Xstatic short nplayers;
Xstatic int stlinecount = 1;
X
Xextern unsigned char	newcourse();	/* Down below... */
X
Xintrupt()
X{
X    register int		i;
X    register struct player	*p;
X
X    udcounter++;
X    move();
X    ++stlinecount;
X}
X
Xredraw(j)
Xregister struct player	*j;
X{
X    /* erase warning line if necessary */
X    if ((j->p_warntimer <= udcounter) && (j->p_warncount > 0)) {
X	XClearWindow(j->display, j->warnw);
X	j->p_warncount = 0;
X    }
X
X    if (j->clearcount) {
X	XFillRectangles(j->display, j->w, j->cleargc,
X		j->clearzone, j->clearcount);
X	j->clearcount = 0;
X    }
X
X/* NOTE: Can this be made into an XDrawLines? */
X    while (j->clearlcount) {
X	j->clearlcount--;
X	XDrawLine(j->display, j->w, j->cleargc,
X	    j->clearline[0][j->clearlcount],
X	    j->clearline[1][j->clearlcount],
X	    j->clearline[2][j->clearlcount],
X	    j->clearline[3][j->clearlcount]);
X    }
X
X    if ((j->p_mapmode) && (udcounter % ((nplayers == 0) ? 1 : nplayers) == 0))
X	map(j);
X
X    /* Display a new message every MESSTIME/UPS seconds */
X    if ((udcounter % MESSTIME) == 0)
X	dmessage(j);
X
X    local(j);	/* redraw local window */
X
X    if ((stlinecount&02) == 0)
X	stline(j);	/* update every 4 times we update the window */
X
X    if (j->p_flags & PFSHOWSTATS)
X	updateStats(j, j->statwin);
X}
X
XdrawPartialPhaser(p, j)
Xregister struct player *p, *j;
X{
Xint	sx,ex,sy,ey;
Xstruct	phaser *php;
X
X
X    sx= j->p_ship->s_x - p->p_ship->s_x;
X    sy= j->p_ship->s_y - p->p_ship->s_y;
X    /* Now draw his phaser (if it exists) */
X    php = &phasers[j->p_ship->s_no];
X    if (php->ph_status == PHMISS) {
X	/* Here I will have to compute end coordinate */
X	phasedist(j, php, &ex, &ey);
X	ex -= p->p_ship->s_x;
X	ey -= p->p_ship->s_y;
X    }
X    else {
X	ex = (players[php->ph_target].p_ship->s_x) - p->p_ship->s_x;
X	ey = (players[php->ph_target].p_ship->s_y) - p->p_ship->s_y;
X    }
X    /* phaser end points are now relative to our position, make them
X     * relative to window origin (so X clips them correctly)
X     */
X    sx= sx/SCALE+p->p_xwinsize/2; sy= sy/SCALE+p->p_ywinsize/2;
X    ex= ex/SCALE+p->p_xwinsize/2; ey= ey/SCALE+p->p_ywinsize/2;
X    if ((sx<0)&&(ex<0))	return;
X    if ((sy<0)&&(ey<0))	return;
X    if ((sx>p->p_xwinsize)&&(ex>p->p_xwinsize))	return;
X    if ((sy>p->p_ywinsize)&&(ey>p->p_ywinsize))	return;
X    XSetForeground(p->display, p->xfgc, phaserColor(php));
X    XDrawLine(p->display, p->w, p->xfgc,
X	    sx, sy, ex, ey);
X/*
X    p->clearline[p->clearlcount].x1 = sx;
X    p->clearline[p->clearlcount].y1 = sy;
X    p->clearline[p->clearlcount].x2 = ex;
X    p->clearline[p->clearlcount].y2 = ey;
X*/
X    p->clearline[0][p->clearlcount] = sx;
X    p->clearline[1][p->clearlcount] = sy;
X    p->clearline[2][p->clearlcount] = ex;
X    p->clearline[3][p->clearlcount] = ey;
X    p->clearlcount++;
X}
X
Xlocal(p)
Xregister struct player *p;
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    register struct ship	*towee;
X    char glyph;
X    int dx, dy;
X    int xview, yview;
X
X    /* Draw Planets */
X    xview = SCALE * p->p_xwinsize / 2;
X    yview = SCALE * p->p_ywinsize / 2;
X    for (i = 0, l = &planets[0]; i < MAXPLANETS; i++, l++) {
X	if (l->pl_flags & PLINVIS)
X		continue;
X	dx = l->pl_x - p->p_ship->s_x;
X	dy = l->pl_y - p->p_ship->s_y;
X	if (dx > xview || dx < -xview || dy > yview || dy < -yview)
X	    continue;
X	dx = dx / SCALE + p->p_xwinsize / 2;
X	dy = dy / SCALE + p->p_ywinsize / 2;
X	glyph = planetGlyph(l);
X	XSetForeground(p->display, p->xfgc, planetColor(l));
X	XDrawString(p->display, p->w, p->xfgc, dx - (planet_width/2),
X		dy - (planet_height/2), &glyph, 1);
X	if (p->p_namemode) {
X	    XDrawImageString(p->display, p->w, p->dfgc, dx - (planet_width/2), dy + (planet_height/2 + p->dfont->ascent),
X		l->pl_name, l->pl_namelen);
X	    p->clearzone[p->clearcount].x = dx - (planet_width/2);
X	    p->clearzone[p->clearcount].y = dy + (planet_height/2);
X	    /*NOTE: put this calculation into the player data */
X	    p->clearzone[p->clearcount].width = XTextWidth(p->dfont, l->pl_name, l->pl_namelen);
X	    p->clearzone[p->clearcount].height = fontHeight(p->dfont);
X	    p->clearcount++;
X	}
X	p->clearzone[p->clearcount].x = dx - (planet_width/2);
X	p->clearzone[p->clearcount].y = dy - (planet_height/2);
X	p->clearzone[p->clearcount].width = planet_width;
X	p->clearzone[p->clearcount].height = planet_height;
X	p->clearcount++;
X    }
X
X    /* Draw ships */
X    nplayers = 0;
X    for (i = 0, j = &players[0]; i < MAXPLAYER; i++, j++) {
X	int tx, ty;
X	if (j->p_status != PALIVE)
X	    continue;
X	if (j->p_ship->s_status == EXPLODE && j->p_ship->s_explode < 0)
X		continue;
X	/* Always draw self or if viewer is God */
X	if (j != p && !isGod(p)) {
X		/* Don't draw enemies or God if they are cloaked */
X		if (iscloaked(j->p_ship) && (!friendlyPlayer(j) || isGod(j)))
X			continue;
X	}
X	nplayers++;
X	dx = j->p_ship->s_x - p->p_ship->s_x;
X	dy = j->p_ship->s_y - p->p_ship->s_y;
X	if (dx > xview || dx < -xview || dy > yview || dy < -yview) {
X	    if (phasers[j->p_ship->s_no].ph_status != PHFREE)
X		drawPartialPhaser(p, j);
X	    continue;
X	}
X	XSetForeground(p->display, p->xfgc, playerColor(j));
X	dx = dx / SCALE + p->p_xwinsize / 2;
X	dy = dy / SCALE + p->p_ywinsize / 2;
X	if (j->p_ship->s_status != EXPLODE) {
X	    if (j->p_ship->s_team == FED)
X		glyph = FED_GLYPHS + rosette(j->p_ship->s_dir);
X	    else if (j->p_ship->s_team == ROM)
X		glyph = ROM_GLYPHS + rosette(j->p_ship->s_dir);
X	    else if (j->p_ship->s_team == KLI)
X		glyph = KLI_GLYPHS + rosette(j->p_ship->s_dir);
X	    else if (j->p_ship->s_team == ORI)
X		glyph = ORI_GLYPHS + rosette(j->p_ship->s_dir);
X	    else if (j->p_ship->s_team == GOD)
X		glyph = GODVIEW;
X
X	    XDrawString(p->display, p->w, p->xfgc,
X	        dx - (ship_width/2), dy - (ship_height/2),
X		&glyph, 1);
X	    if (iscloaked(j->p_ship))
X		XFillRectangle(p->display, p->w, p->dimgc,
X	            dx - (ship_width/2), dy - (ship_height/2),
X		    ship_width, ship_height);
X	/* NOTE: This DrawImageString doesn't use the right GC */
X	    if (j->p_ship->s_team != GOD)
X		    XDrawImageString(p->display, p->w, p->dfgc, dx + (ship_width/2), dy - (ship_height/2 - p->dfont->ascent),
X			shipnos + j->p_ship->s_no, 1);
X	       
X/* NOTE: fix to change shield color depending on damage.. */
X	    if ((p->p_flags & PFSHOWSHIELDS) && (j->p_ship->s_flags & SFSHIELD)) {
X		/* Don't draw shields around God's "ship". */
X		if (j->p_ship->s_team != GOD) {
X			if (j == p) {
X			    if (j->p_ship->s_damage > (j->p_ship->s_maxdamage / 2))
X				glyph = RSHIELD_GLYPH;
X			    else if (j->p_ship->s_shield < (j->p_ship->s_maxshields / 2))
X				glyph = YSHIELD_GLYPH;
X			    else
X				glyph = SHIELD_GLYPH;
X			} else
X			    glyph = SHIELD_GLYPH;
X			XDrawString(p->display, p->w, p->xfgc, dx - (shield_width / 2),
X				dy - (shield_height / 2), &glyph, 1);
X		}
X	    }
X
X	    p->clearzone[p->clearcount].x = dx + (ship_width/2);
X	    p->clearzone[p->clearcount].y = dy - (ship_height/2);
X	    /* NOTE: put this calculattion into  player data */
X	    p->clearzone[p->clearcount].width = XTextWidth(p->dfont, shipnos + j->p_ship->s_no, 1);
X	    p->clearzone[p->clearcount].height = fontHeight(p->dfont);
X	    p->clearcount++;
X	    p->clearzone[p->clearcount].x = dx - (shield_width/2);
X	    p->clearzone[p->clearcount].y = dy - (shield_height/2);
X	    p->clearzone[p->clearcount].width = shield_width;
X	    p->clearzone[p->clearcount].height = shield_height;
X	    p->clearcount++;
X	} else {
X	    glyph = EXP_GLYPHS_LEFT + (10 - j->p_ship->s_explode)/2;
X	    XDrawString(p->display, p->w, p->xfgc, dx - (ex_width / 2),
X		dy - (ex_height / 2), &glyph, 1);
X
X	    glyph = EXP_GLYPHS_RIGHT + (10 - j->p_ship->s_explode)/2;
X	    XDrawString(p->display, p->w, p->xfgc, dx,
X		dy - (ex_height / 2), &glyph, 1);
X
X	    p->clearzone[p->clearcount].x = dx - (ex_width/2);
X	    p->clearzone[p->clearcount].y = dy - (ex_height/2);
X	    p->clearzone[p->clearcount].width = ex_width;
X	    p->clearzone[p->clearcount].height = ex_height;
X	    p->clearcount++;
X	}
X
X	/* Now draw their phaser (if it exists) */
X	php = &phasers[j->p_ship->s_no];
X	if (php->ph_status != PHFREE) {
X	    if (php->ph_status == PHMISS) {
X		/* Here I will have to compute end coordinate */
X		phasedist(j, php, &tx, &ty);
X		tx = (tx - p->p_ship->s_x) / SCALE + p->p_xwinsize / 2;
X		ty = (ty - p->p_ship->s_y) / SCALE + p->p_ywinsize / 2;
X		XSetForeground(p->display, p->xfgc, phaserColor(php));
X		XDrawLine(p->display, p->w, p->xfgc, dx, dy, tx, ty);
X	    }
X	    else { /* Start point is dx, dy */
X		tx = (players[php->ph_target].p_ship->s_x - p->p_ship->s_x) /
X		    SCALE + p->p_xwinsize / 2;
X		ty = (players[php->ph_target].p_ship->s_y - p->p_ship->s_y) /
X		    SCALE + p->p_ywinsize / 2;
X		XSetForeground(p->display, p->xfgc, phaserColor(php));
X		XDrawLine(p->display, p->w, p->xfgc, dx, dy, tx, ty);
X	    }
X	    p->clearline[0][p->clearlcount] = dx;
X	    p->clearline[1][p->clearlcount] = dy;
X	    p->clearline[2][p->clearlcount] = tx;
X	    p->clearline[3][p->clearlcount] = ty;
X	    p->clearlcount++;
X	}
X
X	/* Now, if they are towing someone...draw the tractor beam. */
X	if (j->p_ship->s_flags & SFTOWING) {
X	    towee = &ships[j->p_ship->s_towing];
X	    tx = (towee->s_x - p->p_ship->s_x) /
X		SCALE + p->p_xwinsize / 2;
X	    ty = (towee->s_y - p->p_ship->s_y) /
X		SCALE + p->p_ywinsize / 2;
X	    XSetForeground(p->display, p->tbgc, p->unColor);
X	    XDrawLine(p->display, p->w, p->tbgc, dx, dy, tx, ty);
X	    p->clearline[0][p->clearlcount] = dx;
X	    p->clearline[1][p->clearlcount] = dy;
X	    p->clearline[2][p->clearlcount] = tx;
X	    p->clearline[3][p->clearlcount] = ty;
X	    p->clearlcount++;
X	}
X    }
X
X    /* Draw torps */
X    for (i = 0, j = &players[0]; i < MAXPLAYER; i++, j++) {
X	if (j->p_status != PALIVE)
X		continue;
X	if (!j->p_ship->s_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 - p->p_ship->s_x;
X	    dy = k->t_y - p->p_ship->s_y;
X	    if (dx > xview || dx < -xview || dy > yview || dy < -yview)
X		continue;
X	    XSetForeground(p->display, p->xfgc, torpColor(k));
X	    dx = dx / SCALE + p->p_xwinsize / 2;
X	    dy = dy / SCALE + p->p_ywinsize / 2;
X	    if (k->t_status == TEXPLODE) {
X		glyph = CLOUD_GLYPH;
X		XDrawString(p->display, p->w, p->xfgc, dx - (cloud_width / 2),
X			dy - (cloud_height / 2), &glyph, 1);
X
X		p->clearzone[p->clearcount].x = dx - (cloud_width/2);
X		p->clearzone[p->clearcount].y = dy - (cloud_height/2);
X		p->clearzone[p->clearcount].width = cloud_width;
X		p->clearzone[p->clearcount].height = cloud_height;
X		p->clearcount++;
X	    }
X	    else if (k->t_owner != p->p_ship->s_no && ((k->t_war & (1 << p->p_ship->s_team)) ||
X		      ((1 << k->t_team) & (p->p_ship->s_hostile | p->p_ship->s_swar))))
X	    {
X		glyph = ETORP_GLYPH;
X		XDrawString(p->display, p->w, p->xfgc, dx - (etorp_width / 2),
X			dy - (etorp_height / 2), &glyph, 1);
X
X		p->clearzone[p->clearcount].x = dx - (etorp_width/2);
X		p->clearzone[p->clearcount].y = dy - (etorp_height/2);
X		p->clearzone[p->clearcount].width = etorp_width;
X		p->clearzone[p->clearcount].height = etorp_height;
X		p->clearcount++;
X	    }
X	    else {
X		glyph = MTORP_GLYPH;
X		XDrawString(p->display, p->w, p->xfgc, dx - (mtorp_width / 2),
X			dy - (mtorp_height / 2), &glyph, 1);
X
X		p->clearzone[p->clearcount].x = dx - (mtorp_width/2);
X		p->clearzone[p->clearcount].y = dy - (mtorp_height/2);
X		p->clearzone[p->clearcount].width = mtorp_width;
X		p->clearzone[p->clearcount].height = mtorp_height;
X		p->clearcount++;
X	    }
X	}
X    }
X
X    /* Draw Edges */
X    XSetForeground(p->display, p->xfgc, p->warningColor);
X    if (p->p_ship->s_x < (p->p_xwinsize / 2) * SCALE) {
X	int	sy, ey;
X
X	dx = (p->p_xwinsize / 2) - (p->p_ship->s_x) / SCALE;
X	sy = (p->p_ywinsize / 2) + (0 - p->p_ship->s_y) / SCALE;
X	ey = (p->p_ywinsize / 2) + (GWIDTH - p->p_ship->s_y) / SCALE;
X	if (sy < 0) sy = 0;
X	if (ey > p->p_ywinsize - 1) ey = p->p_ywinsize - 1;
X	XDrawLine(p->display, p->w, p->xfgc, dx, sy, dx, ey);
X	p->clearline[0][p->clearlcount] = dx;
X	p->clearline[1][p->clearlcount] = sy;
X	p->clearline[2][p->clearlcount] = dx;
X	p->clearline[3][p->clearlcount] = ey;
X	p->clearlcount++;
X    }
X
X    if ((GWIDTH - p->p_ship->s_x) < (p->p_xwinsize / 2) * SCALE) {
X	int	sy, ey;
X
X	dx = (p->p_xwinsize / 2) + (GWIDTH - p->p_ship->s_x) / SCALE;
X	sy = (p->p_ywinsize / 2) + (0 - p->p_ship->s_y) / SCALE;
X	ey = (p->p_ywinsize / 2) + (GWIDTH - p->p_ship->s_y) / SCALE;
X	if (sy < 0) sy = 0;
X	if (ey > p->p_ywinsize - 1) ey = p->p_ywinsize - 1;
X	XDrawLine(p->display, p->w, p->xfgc, dx, sy, dx, ey);
X	p->clearline[0][p->clearlcount] = dx;
X	p->clearline[1][p->clearlcount] = sy;
X	p->clearline[2][p->clearlcount] = dx;
X	p->clearline[3][p->clearlcount] = ey;
X	p->clearlcount++;
X    }
X
X    if (p->p_ship->s_y < (p->p_ywinsize / 2) * SCALE) {
X	int	sx, ex;
X
X	dy = (p->p_ywinsize / 2) - (p->p_ship->s_y) / SCALE;
X	sx = (p->p_xwinsize / 2) + (0 - p->p_ship->s_x) / SCALE;
X	ex = (p->p_xwinsize / 2) + (GWIDTH - p->p_ship->s_x) / SCALE;
X	if (sx < 0) sx = 0;
X	if (ex > p->p_xwinsize - 1) ex = p->p_xwinsize - 1;
X	XDrawLine(p->display, p->w, p->xfgc, sx, dy, ex, dy);
X	p->clearline[0][p->clearlcount] = sx;
X	p->clearline[1][p->clearlcount] = dy;
X	p->clearline[2][p->clearlcount] = ex;
X	p->clearline[3][p->clearlcount] = dy;
X	p->clearlcount++;
X    }
X
X    if ((GWIDTH - p->p_ship->s_y) < (p->p_ywinsize / 2) * SCALE) {
X	int	sx, ex;
X
X	dy = (p->p_ywinsize / 2) + (GWIDTH - p->p_ship->s_y) / SCALE;
X	sx = (p->p_xwinsize / 2) + (0 - p->p_ship->s_x) / SCALE;
X	ex = (p->p_xwinsize / 2) + (GWIDTH - p->p_ship->s_x) / SCALE;
X	if (sx < 0) sx = 0;
X	if (ex > p->p_xwinsize - 1) ex = p->p_xwinsize - 1;
X	XDrawLine(p->display, p->w, p->xfgc, sx, dy, ex, dy);
X	p->clearline[0][p->clearlcount] = sx;
X	p->clearline[1][p->clearlcount] = dy;
X	p->clearline[2][p->clearlcount] = ex;
X	p->clearline[3][p->clearlcount] = dy;
X	p->clearlcount++;
X    }
X
X    /* Change border color to signify alert status */
X    if (p->p_ship->s_oldalert != (p->p_ship->s_flags & (SFGREEN|SFYELLOW|SFRED))) {
X        p->p_ship->s_oldalert = (p->p_ship->s_flags & (SFGREEN|SFYELLOW|SFRED));
X	switch (p->p_ship->s_oldalert) {
X	    case SFGREEN:
X	        if (!p->mono) {
X		    XSetWindowBorder(p->display, p->baseWin, p->gColor);
X/*ICCCM 4.1.9	    XSetWindowBorder(p->display, p->iconWin, p->gColor); */
X	        } else {
X		    XSetWindowBorderPixmap(p->display, p->baseWin, p->gTile);
X/*ICCCM 4.1.9	    XSetWindowBorderPixmap(p->display, p->iconWin, p->gTile); */
X		}
X		break;
X	    case SFYELLOW:
X	        if (!p->mono) {
X		    XSetWindowBorder(p->display, p->baseWin, p->yColor);
X/*ICCCM 4.1.9	    XSetWindowBorder(p->display, p->iconWin, p->yColor); */
X	        } else {
X		    XSetWindowBorderPixmap(p->display, p->baseWin, p->yTile);
X/*ICCCM 4.1.9	    XSetWindowBorderPixmap(p->display, p->iconWin, p->yTile); */
X		}
X		break;
X	    case SFRED:
X	        if (!p->mono) {
X		    XSetWindowBorder(p->display, p->baseWin, p->rColor);
X/*ICCCM 4.1.9	    XSetWindowBorder(p->display, p->iconWin, p->rColor); */
X	        } else {
X		    XSetWindowBorderPixmap(p->display, p->baseWin, p->rTile);
X/*ICCCM 4.1.9	    XSetWindowBorderPixmap(p->display, p->iconWin, p->rTile); */
X		}
X		break;
X	}
X    }
X}
X
X/*
X * compute position of the end of the phaser
X * and return in tx and ty.
X */
Xphasedist(j, php, tx, ty)
X    struct player *j;
X    struct phaser *php;
X    int *tx, *ty;
X{
X	*tx = j->p_ship->s_x + (int) (((j->p_ship->s_phasedist) * icos[php->ph_dir]) >> TRIGSCALE);
X	*ty = j->p_ship->s_y + (int) (((j->p_ship->s_phasedist) * isin[php->ph_dir]) >> TRIGSCALE);
X}
X
Xmap(p)
Xregister struct player	*p;
X{
X    register int		i;
X    register struct player	*j;
X    register struct planet	*l;
X    int				dx, dy;
X    char			glyph;
X
X    if (p->p_redrawall) {
X	XClearWindow(p->display, p->mapw);
X	p->mclearcount = 0;
X    } else if (p->mclearcount) {
X	XFillRectangles(p->display, p->mapw, p->cleargc,
X		p->mclearzone, p->mclearcount);
X	p->mclearcount = 0;
X    }
X
X    /* Draw Planets */
X    for (i = 0, l = &planets[0]; i < MAXPLANETS; i++, l++) {
X	if (l->pl_flags & PLINVIS)
X		continue;
X	if ((l->pl_drawtime < p->p_ship->s_updates) && (!p->p_redrawall))
X	    continue;
X	dx = l->pl_x * p->p_xwinsize / GWIDTH;
X	dy = l->pl_y * p->p_ywinsize / GWIDTH;
X
X	if (l->pl_orbvel && p->mpzset[l->pl_no] && !p->p_redrawall) {
X		/* Erase its last position... */
X		XFillRectangles(p->display, p->mapw, p->cleargc,
X			&p->mpzone[l->pl_no * 2], 2);
X		p->mpzset[l->pl_no] = 0;
X	}
X	glyph = mplanetGlyph(l);
X	XSetForeground(p->display, p->xfgc, planetColor(l));
X	XDrawString(p->display, p->mapw, p->xfgc, dx - (mplanet_width / 2),
X		dy - (mplanet_height / 2), &glyph, 1);
X	XDrawImageString(p->display, p->mapw, p->dfgc, dx - (mplanet_width/2), dy + (mplanet_height/2 + p->dfont->ascent),
X	    l->pl_name, 3);
X
X	if (l->pl_orbvel) {
X		/* Save its present position... */
X		p->mpzone[l->pl_no * 2].x = dx - (mplanet_width/2);
X		p->mpzone[l->pl_no * 2].y = dy + (mplanet_height/2);
X		/* NOTE: Put this calculation into player data */
X		p->mpzone[l->pl_no * 2].width = XTextWidth(p->dfont, l->pl_name, 3);
X		p->mpzone[l->pl_no * 2].height = fontHeight(p->dfont);
X		p->mpzone[l->pl_no * 2 + 1].x = dx - (mplanet_width/2);
X		p->mpzone[l->pl_no * 2 + 1].y = dy - (mplanet_height/2);
X		p->mpzone[l->pl_no * 2 + 1].width = mplanet_width;
X		p->mpzone[l->pl_no * 2 + 1].height = mplanet_height;
X		p->mpzset[l->pl_no] = 1;
X	}
X    }
X    p->p_redrawall = 0;
X
X    /* Draw ships */
X    nplayers = 0;
X    for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
X	char	*str;
X
X	if (j->p_status != PALIVE)
X	    continue;
X	/* NOTE: This counter includes ALL team members. */
X	nplayers++;
X	dx = j->p_ship->s_x * p->p_xwinsize / GWIDTH;
X	dy = j->p_ship->s_y * p->p_ywinsize / GWIDTH;
X	if (isGod(p) || !iscloaked(j->p_ship) || friendlyPlayer(j)) {
X		/* NOTE: put these calculations into the player data */
X	    XDrawImageString(p->display, p->mapw, p->dfgc, dx - XTextWidth(p->dfont, j->p_mapchars, 2), dy - fontHeight(p->dfont)/2 + p->dfont->ascent,
X		str = j->p_mapchars, 2);
X	    p->mclearzone[p->mclearcount].x = dx - XTextWidth(p->dfont, j->p_mapchars, 2);
X	    p->mclearzone[p->mclearcount].y = dy - fontHeight(p->dfont)/2;
X	    p->mclearzone[p->mclearcount].width = XTextWidth(p->dfont, str, 2);
X	    p->mclearzone[p->mclearcount].height = fontHeight(p->dfont);
X	    p->mclearcount++;
X	}
X    }
X}
X
Xstline(p)
Xregister struct player	*p;
X{
X/*                         0123456789012345678901234567890123456789012345678901234567890*/
X    static char buf[80] = "               0     0 100   0    0.00    0  10000    0     0";
X
X    /* Instead of one sprintf, we do all this by hand for optimization */
X
X    if (buf[0] == 0) {
X	int i;
X	for (i = 0; i < 63; ++i)
X	    buf[i] = ' ';
X    }
X
X    buf[0] = (p->p_ship->s_flags & SFSHIELD ? 'S': ' ');
X    if (p->p_ship->s_flags & SFGREEN)
X	buf[1] = 'G';
X    else if (p->p_ship->s_flags & SFYELLOW)
X	buf[1] = 'Y';
X    else if (p->p_ship->s_flags & SFRED)
X	buf[1] = 'R';
X    buf[2] = (p->p_ship->s_flags & (SFPLLOCK | SFSLOCK) ? 'L': ' ');
X    buf[3] = (p->p_ship->s_flags & SFREPAIR ? 'R': ' ');
X    buf[4] = (p->p_ship->s_flags & SFBOMB ? 'B': ' ');
X    buf[5] = (p->p_ship->s_flags & SFORBIT ? 'O': ' ');
X    if ((p->p_ship->s_flags & SFCLOAK) && !(p->p_ship->s_flags & SFDCLOAK))
X	buf[6] = 'C';
X    else
X	buf[6] = ' ';
X    buf[7] = (p->p_ship->s_flags & SFWEP ? 'W': ' ');
X    buf[8] = (p->p_ship->s_flags & SFENG ? 'E': ' ');
X    buf[9] = (p->p_ship->s_flags & SFBEAMUP ? 'u': ' ');
X    buf[10] = (p->p_ship->s_flags & SFBEAMDOWN ? 'd': ' ');
X    buf[11] = (p->p_flags & PFCOPILOT ? 'P' : ' ');
X    buf[14] = '0' + (p->p_ship->s_speed / 10);	/* speed */
X    if (buf[14] == '0')
X	buf[14] = ' ';
X    buf[15] = '0' + (p->p_ship->s_speed % 10);	/* speed */
X    buf[19] = '0' + (p->p_ship->s_damage / 100);
X    if (buf[19] == '0')
X	buf[19] = ' ';
X    buf[20] = '0' + ((p->p_ship->s_damage % 100) / 10);
X    if ((buf[20] == '0') && (p->p_ship->s_damage < 100))
X	buf[20] = ' ';
X    buf[21] = '0' + (p->p_ship->s_damage % 10);
X    buf[23] = '0' + (p->p_ship->s_shield / 100);
X    if (buf[23] == '0')
X	buf[23] = ' ';
X    buf[24] = '0' + ((p->p_ship->s_shield % 100) / 10);
X    if ((buf[24] == '0') && (p->p_ship->s_shield < 100))
X	buf[24] = ' ';
X    buf[25] = '0' + (p->p_ship->s_shield % 10);
X    buf[28] = '0' + ((p->p_ship->s_ntorp % 100) / 10);
X    if (buf[28] == '0')
X	buf[28] = ' ';
X    buf[29] = '0' + (p->p_ship->s_ntorp % 10);
X    buf[33] = '0' + ((int) (p->p_ship->s_stats.st_kills / 10));
X    if (buf[33] == '0')
X	buf[33] = ' ';
X    buf[34] = '0' + (((int) p->p_ship->s_stats.st_kills) % 10);
X    buf[35] = '.';
X    buf[36] = '0' + (((int) (p->p_ship->s_stats.st_kills * 10)) % 10);
X    buf[37] = '0' + (((int) (p->p_ship->s_stats.st_kills * 100)) % 10);
X    buf[41] = '0' + ((p->p_ship->s_armies % 100) / 10);
X    if (buf[41] == '0')
X	buf[41] = ' ';
X    buf[42] = '0' + (p->p_ship->s_armies % 10);
X
X    buf[45] = '0' + (p->p_ship->s_fuel / 10000);
X    if (buf[45] == '0')
X	buf[45] = ' ';
X    buf[46] = '0' + ((p->p_ship->s_fuel % 10000) / 1000);
X    if ((buf[46] == '0') && (p->p_ship->s_fuel < 10000))
X	buf[46] = ' ';
X    buf[47] = '0' + ((p->p_ship->s_fuel % 1000) / 100);
X    if ((buf[47] == '0') && (p->p_ship->s_fuel < 1000))
X	buf[47] = ' ';
X    buf[48] = '0' + ((p->p_ship->s_fuel % 100) / 10);
X    if ((buf[48] == '0') && (p->p_ship->s_fuel < 100))
X	buf[48] = ' ';
X    buf[49] = '0' + (p->p_ship->s_fuel % 10);
X
X    buf[52] = '0' + ((p->p_ship->s_wtemp / 10) / 100);
X    if (buf[52] == '0')
X	buf[52] = ' ';
X    buf[53] = '0' + (((p->p_ship->s_wtemp / 10) % 100) / 10);
X    if ((buf[53] == '0') && (p->p_ship->s_wtemp < 1000))
X	buf[53] = ' ';
X    buf[54] = '0' + ((p->p_ship->s_wtemp / 10) % 10);
X
X    buf[58] = '0' + ((p->p_ship->s_etemp / 10) / 100);
X    if (buf[58] == '0')
X	buf[58] = ' ';
X    buf[59] = '0' + (((p->p_ship->s_etemp / 10) % 100) / 10);
X    if ((buf[59] == '0') && (p->p_ship->s_etemp < 1000))
X	buf[59] = ' ';
X    buf[60] = '0' + ((p->p_ship->s_etemp / 10) % 10);
X    buf[61] = '\0';
X
X    /* Draw status line */
X    if (!p->p_ts_offset)
X	redrawTstats(p);
X    XDrawImageString(p->display, p->tstatw, p->dfgc, p->p_ts_offset, 20 + p->dfont->ascent, buf, 61);
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 & SFGREEN)
X	alertchar = 'G';
X    else if (me->p_flags & SFYELLOW)
X	alertchar = 'Y';
X    else if (me->p_flags & SFRED)
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 & SFSHIELD ? 'S': ' '),
X	alertchar,
X	(me->p_flags & (SFPLLOCK | SFSLOCK) ? 'L': ' '),
X	(me->p_flags & SFREPAIR ? 'R': ' '),
X	(me->p_flags & SFBOMB ? 'B': ' '),
X	(me->p_flags & SFORBIT ? 'O': ' '),
X	(me->p_flags & SFCLOAK ? 'C': ' '),
X	(me->p_flags & SFWEP ? 'W': ' '),
X	(me->p_flags & SFENG ? 'E': ' '),
X	(me->p_flags & SFBEAMUP ? 'u': ' '),
X	(me->p_flags & SFBEAMDOWN ? '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_ship->s_stats.st_kills,
X	me->p_armies,
X	me->p_fuel,
X	me->p_wtemp/10,
X	me->p_etemp/10);
X    XDrawImageString(display, tstatw, dfgc, 50, 20, buf, strlen(buf));
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(p)
Xregister struct player	*p;
X{
X    register int		i;
X    char buf[80];
X    struct player *pl;
X    struct planet *pln;
X
X    if (p->p_ship->s_flags & SFSELFDEST) {
X#ifdef notdef
X	if ((p->p_ship->s_updates >= p->p_ship->s_selfdest) ||
X	    ((p->p_flags & SFGREEN) && (p->p_damage == 0)
X		&& (p->p_shield == 100)))
X#else
X	if (p->p_ship->s_updates >= p->p_ship->s_selfdest)
X#endif
X	{
X	    p->p_ship->s_flags &= ~SFSELFDEST;
X	    p->p_ship->s_explode = PEXPTIME;
X	    p->p_ship->s_whydead = KQUIT;
X	    p->p_ship->s_status = EXPLODE;
X	}
X	else {
X	    sprintf(buf, "Self Destruct in %d seconds",
X		(p->p_ship->s_selfdest - p->p_ship->s_updates) / UPS);
X	    warning(p, buf);
X	}
X    }
X    /* give certain information about bombing or beaming */
X    if (p->p_ship->s_flags & SFBOMB) {
X	if (planets[p->p_ship->s_planet].pl_armies < 5) {
X	    sprintf(buf, "Cannot bomb %s while armies are less than 5",
X		planets[p->p_ship->s_planet].pl_name);
X	    warning(p, buf);
X	    p->p_ship->s_flags &= ~SFBOMB;
X	}
X	else {
X	    sprintf(buf, "Bombing %s.  %d armies left",
X		planets[p->p_ship->s_planet].pl_name,
X		planets[p->p_ship->s_planet].pl_armies);
X	    warning(p, buf);
X	}
X    }
X
X    if (p->p_ship->s_flags & SFBEAMUP) {
X	if (planets[p->p_ship->s_planet].pl_armies < 5) {
X	    sprintf(buf, "%s: Too few armies to beam up",
X		planets[p->p_ship->s_planet].pl_name);
X	    warning(p, buf);
X	    p->p_ship->s_flags &= ~SFBEAMUP;
X	}
X	else if ((p->p_ship->s_armies == (int) (p->p_ship->s_stats.st_kills * 2)) ||
X	    (p->p_ship->s_armies == p->p_ship->s_maxarmies)) {
X		sprintf(buf, "No more room on board for armies");
X	    warning(p, buf);
X	    p->p_ship->s_flags &= ~SFBEAMUP;
X	}
X	else {
X	    sprintf(buf, "Beaming up.  (%d/%d)", p->p_ship->s_armies,
X		((p->p_ship->s_stats.st_kills * 2) > p->p_ship->s_maxarmies) ?
X		    p->p_ship->s_maxarmies : (int) (p->p_ship->s_stats.st_kills * 2));
X	    warning(p, buf);
X	}
X    }
X    if (p->p_ship->s_flags & SFBEAMDOWN) {
X	if (p->p_ship->s_armies == 0) {
X	    sprintf(buf, "No more armies to beam down to %s.",
X		planets[p->p_ship->s_planet].pl_name);
X	    warning(p, buf);
X	    p->p_ship->s_flags &= ~SFBEAMDOWN;
X	}
X	else {
X	    sprintf(buf, "Beaming down.  (%d/%d) %s has %d armies left",
X		p->p_ship->s_armies,
X		((p->p_ship->s_stats.st_kills * 2) > p->p_ship->s_maxarmies) ?
X		    p->p_ship->s_maxarmies : (int) (p->p_ship->s_stats.st_kills * 2),
X		planets[p->p_ship->s_planet].pl_name,
X		planets[p->p_ship->s_planet].pl_armies);
X	    warning(p, buf);
X	}
X    }
X    if (p->p_ship->s_flags & SFREPAIR) {
X	if ((p->p_ship->s_damage == 0) && (p->p_ship->s_shield == p->p_ship->s_maxshields))
X		p->p_ship->s_flags &= ~SFREPAIR;
X    }
X    if (p->p_ship->s_flags & SFSLOCK) { 	/* set course to player x */
X	pl = &players[p->p_ship->s_shipl];
X	if (pl->p_status != PALIVE)
X	    p->p_ship->s_flags &= ~SFSLOCK;
X	if (isGod(p)) {
X		p->p_ship->s_x = pl->p_ship->s_x;
X		p->p_ship->s_y = pl->p_ship->s_y;
X	} else {
X		/* Locks on cloaked ships can fail.. */
X		if ((pl->p_ship->s_flags & SFCLOAK) && !(pl->p_ship->s_flags & SFDCLOAK)) {
X			if ((random() % 100) >= (pl->p_ship->s_damage * 2)) {
X				p->p_ship->s_flags &= ~SFSLOCK;
X			}
X		}
X	}
X	set_course(p, newcourse(p, pl->p_ship->s_x, pl->p_ship->s_y));
X    }
X    if (p->p_ship->s_flags & SFPLLOCK) { 	/* set course to planet x */
X	int dist;
X	pln = &planets[p->p_ship->s_planet];
X	if (isGod(p)) {
X		p->p_ship->s_x = pln->pl_x;
X		p->p_ship->s_y = pln->pl_y;
X		return;
X	}
X	dist = hypot((double) (p->p_ship->s_x - pln->pl_x),
X	    (double) (p->p_ship->s_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 * ((p->p_ship->s_speed * (p->p_ship->s_speed+1)) + 10)))
X	    set_speed(p, ORBSPEED);
X	if ((dist < ORBDIST) && (p->p_ship->s_speed <= ORBSPEED))  {
X	    p->p_ship->s_flags &= ~SFPLLOCK;
X	    orbit(p);
X	}
X	else {
X	    set_course(p, newcourse(p, pln->pl_x, pln->pl_y));
X	}
X    }
X}
X
Xunsigned char
Xnewcourse(p, x, y)
Xregister struct player	*p;
Xregister int		x, y;
X{
X	unsigned char	iatan2();
X
X	return(iatan2(x - p->p_ship->s_x, p->p_ship->s_y - y));
X}
X
XredrawTstats(p)
Xregister struct player	*p;
X{
X    char	buf[BUFSIZ];
X
X    sprintf(buf, 
X	"Flags        warp  dam shd torps kills armies fuel wtemp etemp");
X    if (!p->p_ts_offset)
X	p->p_ts_offset = (p->p_xwinsize - XTextWidth(p->dfont, buf, strlen(buf))) / 2;
X    XDrawImageString(p->display, p->tstatw, p->dfgc, p->p_ts_offset, 10 + p->dfont->ascent, buf, strlen(buf));
X}
END_OF_redraw.c
if test 28816 -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 8 \(of 11\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.