|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 17099 (0x42cb)
Types: TextFile
Names: »redraw.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/xtrek/redraw.c«
#ifndef lint
static char *rcsid_redraw_c = "$Header: redraw.c,v 10.1 86/11/30 15:27:33 jg Rel $";
#endif lint
/* Copyright (c) 1986 Chris Guthrie */
#include <X/Xlib.h>
#include <stdio.h>
#include <signal.h>
#include "defs.h"
#include "struct.h"
#include "data.h"
#include "bitmaps.h"
#define WINSIDE 500
int remap[9] = { -1, 0, 1, -1, 2, -1, -1, -1, 3 };
extern Window w, mapw, statwin, warnw, tstatw, baseWin;
char *shipnos = "0123456789abcdef";
extern char teamlet[];
extern double sin[], cos[], atan2(), hypot();
int clearzone[4][(MAXTORP + 1) * MAXPLAYER + MAXPLANETS];
int clearcount;
int clearline[4][MAXPLAYER];
int clearlcount;
int mclearzone[4][MAXPLAYER + MAXPLANETS]; /* For map window */
int mclearcount;
int udcounter;
extern int redrawall;
extern int warncount;
extern int warntimer;
extern int selfdest;
short nplayers;
extern copilot;
intrupt()
{
signal(SIGALRM, SIG_IGN);
udcounter++;
if ((me->p_status == PDEAD) && (me->p_ntorp == 0))
death();
auto_features();
redraw();
signal(SIGALRM, intrupt);
}
redraw()
{
/* erase warning line if necessary */
if ((warntimer <= udcounter) && (warncount > 0)) {
XPixSet(warnw, 5, 5, dfontinfo->width * warncount, dfontinfo->height,
backColor);
warncount = 0;
}
while (clearcount) {
clearcount--;
XPixSet(w, clearzone[0][clearcount], clearzone[1][clearcount],
clearzone[2][clearcount], clearzone[3][clearcount],
backColor);
}
while (clearlcount) {
clearlcount--;
XLine(w, clearline[0][clearlcount], clearline[1][clearlcount],
clearline[2][clearlcount], clearline[3][clearlcount],
1, 1, backColor, GXcopy, AllPlanes);
}
if ((mapmode) && (udcounter % ((nplayers == 0) ? 1 : nplayers) == 0))
map();
if (udcounter % 20 == 0)
dmessage();
local(); /* redraw local window */
stline();
}
int oldalert = PFGREEN; /* Avoid changing more than we have to. */
local()
{
char buf[80];
register int i;
register struct player *j;
register struct torp *k;
register struct planet *l;
register struct phaser *php;
int junk;
int dx, dy;
int view;
/*
robot();
*/
/* Draw Planets */
for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
dx = l->pl_x - me->p_x;
dy = l->pl_y - me->p_y;
view = SCALE * WINSIDE / 2;
if (dx > view || dx < -view || dy > view || dy < -view)
continue;
dx = dx / SCALE + WINSIDE / 2;
dy = dy / SCALE + WINSIDE / 2;
XPixFill(w, dx - (planet_width/2), dy - (planet_height/2),
planet_width, planet_height,
planetColor(l), bplanet, GXcopy, AllPlanes);
XText(w, dx - (planet_width/2), dy + (planet_height/2),
l->pl_name, strlen(l->pl_name), planetFont(l),
planetColor(l), backColor);
clearzone[0][clearcount] = dx - (planet_width/2);
clearzone[1][clearcount] = dy + (planet_height/2);
clearzone[2][clearcount] = dfontinfo->width * strlen(l->pl_name);
clearzone[3][clearcount] = dfontinfo->height;
clearcount++;
clearzone[0][clearcount] = dx - (planet_width/2);
clearzone[1][clearcount] = dy - (planet_height/2);
clearzone[2][clearcount] = planet_width;
clearzone[3][clearcount] = planet_height;
clearcount++;
}
/* Draw ships */
nplayers = 0;
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
int tx, ty;
if ((j->p_status != PALIVE) && (j->p_status != PEXPLODE))
continue;
if (j->p_flags & PFCLOAK)
continue;
nplayers++;
dx = j->p_x - me->p_x;
dy = j->p_y - me->p_y;
view = SCALE * WINSIDE / 2;
if (dx > view || dx < -view || dy > view || dy < -view)
continue;
dx = dx / SCALE + WINSIDE / 2;
dy = dy / SCALE + WINSIDE / 2;
if (j->p_status == PALIVE) {
switch (j->p_team) {
case FED:
XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
ship_width, ship_height, playerColor(j),
fedview[rosette(j->p_dir)], GXcopy, AllPlanes);
break;
case ROM:
XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
ship_width, ship_height, playerColor(j),
romview[rosette(j->p_dir)], GXcopy, AllPlanes);
break;
case KLI:
XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
ship_width, ship_height, playerColor(j),
kliview[rosette(j->p_dir)], GXcopy, AllPlanes);
break;
case ORI:
XPixFill(w, dx - (ship_width/2), dy - (ship_height/2),
ship_width, ship_height, playerColor(j),
oriview[rosette(j->p_dir)], GXcopy, AllPlanes);
break;
}
XText(w, dx + (ship_width/2), dy - (ship_height/2),
shipnos + j->p_no, 1, shipFont(j), playerColor(j), backColor);
if (showShields && j->p_flags & PFSHIELD)
XPixFill(w, dx - (shield_width/2), dy - (shield_height/2),
shield_width, shield_height, playerColor(j),
shield, GXcopy, AllPlanes);
clearzone[0][clearcount] = dx + (shield_width/2);
clearzone[1][clearcount] = dy - (shield_height/2);
clearzone[2][clearcount] = dfontinfo->width;
clearzone[3][clearcount] = dfontinfo->height;
clearcount++;
clearzone[0][clearcount] = dx - (shield_width/2);
clearzone[1][clearcount] = dy - (shield_height/2);
clearzone[2][clearcount] = shield_width;
clearzone[3][clearcount] = shield_height;
clearcount++;
}
else if (j->p_status == PEXPLODE) {
XPixFill(w, dx - (ex_width/2), dy - (ex_height/2),
ex_width, ex_height, playerColor(j),
expview[(10 - j->p_explode)/2], GXcopy, AllPlanes);
clearzone[0][clearcount] = dx - (ex_width/2);
clearzone[1][clearcount] = dy - (ex_height/2);
clearzone[2][clearcount] = ex_width;
clearzone[3][clearcount] = ex_height;
clearcount++;
}
/* Now draw his phaser (if it exists) */
php = &phasers[j->p_no];
if (php->ph_status != PHFREE) {
if (php->ph_status == PHMISS) {
/* Here I will have to compute end coordinate */
tx = j->p_x + PHASEDIST * cos[php->ph_dir];
ty = j->p_y + PHASEDIST * sin[php->ph_dir];
tx = (tx - me->p_x) / SCALE + WINSIDE / 2;
ty = (ty - me->p_y) / SCALE + WINSIDE / 2;
XLine(w, dx, dy, tx, ty, 1, 1, phaserColor(php),
GXcopy, AllPlanes);
}
else { /* Start point is dx, dy */
tx = (players[php->ph_target].p_x - me->p_x) /
SCALE + WINSIDE / 2;
ty = (players[php->ph_target].p_y - me->p_y) /
SCALE + WINSIDE / 2;
XLine(w, dx, dy, tx, ty, 1, 1, phaserColor(php),
GXcopy, AllPlanes);
}
clearline[0][clearlcount] = dx;
clearline[1][clearlcount] = dy;
clearline[2][clearlcount] = tx;
clearline[3][clearlcount] = ty;
clearlcount++;
}
}
/* Draw torps */
for (i = 0, k = &torps[i]; i < MAXPLAYER * MAXTORP; i++, k++) {
if (!k->t_status)
continue;
dx = k->t_x - me->p_x;
dy = k->t_y - me->p_y;
view = SCALE * WINSIDE / 2;
if (dx > view || dx < -view || dy > view || dy < -view)
continue;
dx = dx / SCALE + WINSIDE / 2;
dy = dy / SCALE + WINSIDE / 2;
if (k->t_status == TEXPLODE) {
XPixFill(w, dx - (cloud_width/2), dy - (cloud_height/2),
cloud_width, cloud_height, torpColor(k),
cloud, GXcopy, AllPlanes);
clearzone[0][clearcount] = dx - (cloud_width/2);
clearzone[1][clearcount] = dy - (cloud_height/2);
clearzone[2][clearcount] = cloud_width;
clearzone[3][clearcount] = cloud_height;
clearcount++;
}
else if (k->t_war & me->p_team) {
XPixFill(w, dx - (etorp_width/2), dy - (etorp_height/2),
etorp_width, etorp_height, torpColor(k),
etorp, GXcopy, AllPlanes);
clearzone[0][clearcount] = dx - (etorp_width/2);
clearzone[1][clearcount] = dy - (etorp_height/2);
clearzone[2][clearcount] = etorp_width;
clearzone[3][clearcount] = etorp_height;
clearcount++;
}
else {
XPixFill(w, dx - (mtorp_width/2), dy - (mtorp_height/2),
mtorp_width, mtorp_height, torpColor(k),
mtorp, GXcopy, AllPlanes);
clearzone[0][clearcount] = dx - (mtorp_width/2);
clearzone[1][clearcount] = dy - (mtorp_height/2);
clearzone[2][clearcount] = mtorp_width;
clearzone[3][clearcount] = mtorp_height;
clearcount++;
}
}
/* Draw Edges */
if (me->p_x < (WINSIDE / 2) * SCALE) {
int sy, ey;
dx = (WINSIDE / 2) - (me->p_x) / SCALE;
sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE;
ey = (WINSIDE / 2) + (GWIDTH - me->p_y) / SCALE;
if (sy < 0) sy = 0;
if (ey > WINSIDE - 1) ey = WINSIDE - 1;
XLine(w, dx, sy, dx, ey, 1, 1, warningColor, GXcopy, AllPlanes);
clearline[0][clearlcount] = dx;
clearline[1][clearlcount] = sy;
clearline[2][clearlcount] = dx;
clearline[3][clearlcount] = ey;
clearlcount++;
}
if ((GWIDTH - me->p_x) < (WINSIDE / 2) * SCALE) {
int sy, ey;
dx = (WINSIDE / 2) + (GWIDTH - me->p_x) / SCALE;
sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE;
ey = (WINSIDE / 2) + (GWIDTH - me->p_y) / SCALE;
if (sy < 0) sy = 0;
if (ey > WINSIDE - 1) ey = WINSIDE - 1;
XLine(w, dx, sy, dx, ey, 1, 1, warningColor, GXcopy, AllPlanes);
clearline[0][clearlcount] = dx;
clearline[1][clearlcount] = sy;
clearline[2][clearlcount] = dx;
clearline[3][clearlcount] = ey;
clearlcount++;
}
if (me->p_y < (WINSIDE / 2) * SCALE) {
int sx, ex;
dy = (WINSIDE / 2) - (me->p_y) / SCALE;
sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE;
ex = (WINSIDE / 2) + (GWIDTH - me->p_x) / SCALE;
if (sx < 0) sx = 0;
if (ex > WINSIDE - 1) ex = WINSIDE - 1;
XLine(w, sx, dy, ex, dy, 1, 1, warningColor, GXcopy, AllPlanes);
clearline[0][clearlcount] = sx;
clearline[1][clearlcount] = dy;
clearline[2][clearlcount] = ex;
clearline[3][clearlcount] = dy;
clearlcount++;
}
if ((GWIDTH - me->p_y) < (WINSIDE / 2) * SCALE) {
int sx, ex;
dy = (WINSIDE / 2) + (GWIDTH - me->p_y) / SCALE;
sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE;
ex = (WINSIDE / 2) + (GWIDTH - me->p_x) / SCALE;
if (sx < 0) sx = 0;
if (ex > WINSIDE - 1) ex = WINSIDE - 1;
XLine(w, sx, dy, ex, dy, 1, 1, warningColor, GXcopy, AllPlanes);
clearline[0][clearlcount] = sx;
clearline[1][clearlcount] = dy;
clearline[2][clearlcount] = ex;
clearline[3][clearlcount] = dy;
clearlcount++;
}
/* Change border color to signify alert status */
if (oldalert != (me->p_flags & (PFGREEN|PFYELLOW|PFRED))) {
oldalert = (me->p_flags & (PFGREEN|PFYELLOW|PFRED));
switch (oldalert) {
case PFGREEN:
XChangeBorder(baseWin, gTile);
break;
case PFYELLOW:
XChangeBorder(baseWin, yTile);
break;
case PFRED:
XChangeBorder(baseWin, rTile);
break;
}
}
}
map()
{
char buf[80];
register int i;
register struct player *j;
register struct planet *l;
int junk;
int dx, dy;
while (mclearcount) {
mclearcount--;
XPixSet(mapw, mclearzone[0][mclearcount], mclearzone[1][mclearcount],
mclearzone[2][mclearcount], mclearzone[3][mclearcount],
backColor);
}
/* Draw Planets */
for (i = 0, l = &planets[i]; i < MAXPLANETS; i++, l++) {
if (!(l->pl_flags & PLREDRAW) && (!redrawall))
continue;
dx = l->pl_x * WINSIDE / GWIDTH;
dy = l->pl_y * WINSIDE / GWIDTH;
XPixFill(mapw, dx - (mplanet_width/2), dy - (mplanet_height/2),
mplanet_width, mplanet_height,
planetColor(l), mbplanet, GXcopy, AllPlanes);
XText(mapw, dx - (mplanet_width/2), dy + (mplanet_height/2),
l->pl_name, 3, planetFont(l), planetColor(l), backColor);
/*
clearzone[0][clearcount] = dx - (mplanet_width/2);
clearzone[1][clearcount] = dy + (mplanet_height/2);
clearzone[2][clearcount] = dfontinfo->width * 3;
clearzone[3][clearcount] = dfontinfo->height;
clearcount++;
clearzone[0][clearcount] = dx - (mplanet_width/2);
clearzone[1][clearcount] = dy - (mplanet_height/2);
clearzone[2][clearcount] = mplanet_width;
clearzone[3][clearcount] = mplanet_height;
clearcount++;
*/
}
redrawall = 0;
/* Draw ships */
nplayers = 0;
for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) {
if (j->p_status != PALIVE)
continue;
nplayers++;
dx = j->p_x * WINSIDE / GWIDTH;
dy = j->p_y * WINSIDE / GWIDTH;
if (j->p_flags & PFCLOAK) {
sprintf(buf, "??");
XText(mapw, dx - dfontinfo->width, dy - dfontinfo->height/2,
buf, 2, shipFont(j), unColor, backColor);
}
else {
sprintf(buf, "%c%x", teamlet[j->p_team], j->p_no);
XText(mapw, dx - dfontinfo->width, dy - dfontinfo->height/2,
buf, 2, shipFont(j), playerColor(j), backColor);
}
mclearzone[0][mclearcount] = dx - dfontinfo->width;
mclearzone[1][mclearcount] = dy - dfontinfo->height/2;
mclearzone[2][mclearcount] = dfontinfo->width * 2;
mclearzone[3][mclearcount] = dfontinfo->height;
mclearcount++;
}
}
stline()
{
char buf[80];
char alertchar = '?';
if (me->p_flags & PFGREEN)
alertchar = 'G';
else if (me->p_flags & PFYELLOW)
alertchar = 'Y';
else if (me->p_flags & PFRED)
alertchar = 'R';
/* Draw status line */
sprintf(buf,
"%c%c%c%c%c%c%c%c%c%c%c%c %1d %3d %3d %2d %5.2f %2d %5d %3d %3d",
(me->p_flags & PFSHIELD ? 'S': ' '),
alertchar,
(me->p_flags & (PFPLLOCK | PFPLOCK) ? 'L': ' '),
(me->p_flags & PFREPAIR ? 'R': ' '),
(me->p_flags & PFBOMB ? 'B': ' '),
(me->p_flags & PFORBIT ? 'O': ' '),
(me->p_flags & PFCLOAK ? 'C': ' '),
(me->p_flags & PFWEP ? 'W': ' '),
(me->p_flags & PFENG ? 'E': ' '),
(me->p_flags & PFBEAMUP ? 'u': ' '),
(me->p_flags & PFBEAMDOWN ? 'd': ' '),
(me->p_flags & PFCOPILOT ? 'P' : ' '),
me->p_speed,
me->p_damage,
me->p_shield,
me->p_ntorp,
me->p_kills,
me->p_armies,
me->p_fuel,
me->p_wtemp/10,
me->p_etemp/10);
XText(tstatw, 50, 20, buf, strlen(buf), dfont, textColor, backColor);
XFlush();
if (showStats)
updateStats(statwin);
}
/* These are routines that need to be done on interrupts but
don't belong in the redraw routine and particularly don't
belong in the daemon. */
auto_features()
{
char buf[80];
struct player *pl;
struct planet *pln;
unsigned char course;
if (copilot && (!(me->p_flags & PFCOPILOT))) {
printf("Owning player has kicked you out\n");
exit(0);
}
if (me->p_flags & PFSELFDEST) {
if ((me->p_updates >= selfdest) ||
((me->p_flags & PFGREEN) && (me->p_damage == 0)
&& (me->p_shield == 100))) {
me->p_flags &= ~PFSELFDEST;
me->p_explode = 10;
me->p_whydead = KQUIT;
me->p_status = PEXPLODE;
}
else {
sprintf(buf, "Self Destruct in %d seconds",
(selfdest - me->p_updates) / 10);
warning(buf);
}
}
/* give certain information about bombing or beaming */
if (me->p_flags & PFBOMB) {
if (planets[me->p_planet].pl_armies < 5) {
sprintf(buf, "Cannot bomb %s while armies are less than 5",
planets[me->p_planet].pl_name);
warning(buf);
me->p_flags &= ~PFBOMB;
}
else {
sprintf(buf, "Bombing %s. %d armies left",
planets[me->p_planet].pl_name,
planets[me->p_planet].pl_armies);
warning(buf);
}
}
if (me->p_flags & PFBEAMUP) {
if (planets[me->p_planet].pl_armies < 5) {
sprintf(buf, "%s: Too few armies to beam up",
planets[me->p_planet].pl_name);
warning(buf);
me->p_flags &= ~PFBEAMUP;
}
else if ((me->p_armies == (int) (me->p_kills * 2)) ||
(me->p_armies == myship->s_maxarmies)) {
sprintf(buf, "No more room on board for armies");
warning(buf);
me->p_flags &= ~PFBEAMUP;
}
else {
sprintf(buf, "Beaming up. (%d/%d)", me->p_armies,
((me->p_kills * 2) > myship->s_maxarmies) ?
myship->s_maxarmies : (int) (me->p_kills * 2));
warning(buf);
}
}
if (me->p_flags & PFBEAMDOWN) {
if (me->p_armies == 0) {
sprintf(buf, "No more armies to beam down to %s.",
planets[me->p_planet].pl_name);
warning(buf);
me->p_flags &= ~PFBEAMDOWN;
}
else {
sprintf(buf, "Beaming down. (%d/%d) %s has %d armies left",
me->p_armies,
((me->p_kills * 2) > myship->s_maxarmies) ?
myship->s_maxarmies : (int) (me->p_kills * 2),
planets[me->p_planet].pl_name,
planets[me->p_planet].pl_armies);
warning(buf);
}
}
if (me->p_flags & PFREPAIR) {
if ((me->p_damage == 0) && (me->p_shield == 100))
me->p_flags &= ~PFREPAIR;
}
if (me->p_flags & PFPLOCK) { /* set course to player x */
pl = &players[me->p_playerl];
if (pl->p_status != PALIVE)
me->p_flags &= ~PFPLOCK;
course = newcourse(pl->p_x, pl->p_y);
set_course(course);
}
if (me->p_flags & PFPLLOCK) { /* set course to planet x */
int dist;
pln = &planets[me->p_planet];
dist = hypot((double) (me->p_x - pln->pl_x),
(double) (me->p_y - pln->pl_y));
/* This is magic. It should be based on defines, but it slows
the ship down to warp two an appropriate distance from the
planet for orbit */
if (dist < (50 * ((me->p_speed * (me->p_speed+1)) + 10)))
set_speed(2);
if ((dist < ORBDIST) && (me->p_speed <= 2)) {
me->p_flags &= ~PFPLLOCK;
orbit();
}
else {
course = newcourse(pln->pl_x, pln->pl_y);
set_course(course);
}
}
}
newcourse(x, y)
int x, y;
{
return((unsigned char) (atan2((double) (x - me->p_x),
(double) (me->p_y - y)) / 3.14159 * 128.));
}
redrawTstats()
{
char buf[BUFSIZ];
sprintf(buf,
"Flags warp dam shd torps kills armies fuel wtemp etemp");
XText(tstatw, 50, 10, buf, strlen(buf), dfont, textColor, backColor);
}