|
|
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 i
Length: 17920 (0x4600)
Types: TextFile
Names: »input.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Xtrek/input.c«
static char sccsid[] = "@(#)input.c 1.2";
/*
Copyright (c) 1986 Chris Guthrie
Permission to use, copy, modify, and distribute this
software and its documentation for any purpose and without
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
documentation. No representations are made about the
suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef SUN40
#include <sys/filio.h>
#else SUN40
#define FD_SET(n, s) (((s)->fds_bits[0]) |= (1 << n))
#define FD_CLR(n, s) (((s)->fds_bits[0]) &= ~(1 << n))
#define FD_ZERO(s) bzero((char *)(s), sizeof (*(s)))
#define FD_ISSET(n, s) (((s)->fds_bits[0]) & (1 << n))
#include <sys/ioctl.h>
#endif
#ifdef hpux
#include <time.h>
#else hpux
#include <sys/time.h>
#endif hpux
#include <signal.h>
#include <errno.h>
#include "defs.h"
#include "data.h"
#define WINSIDE 500
static int doTheRedrawDude, skipUpdates = 1;
int peerdied;
extern Window openStats();
extern char *newwin();
initinput(p)
register struct player *p;
{
XSelectInput(p->display, p->iconWin, ExposureMask);
XSelectInput(p->display, p->w,
KeyPressMask|ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->mapw,
KeyPressMask|ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->messagew,
KeyPressMask|ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->tstatw, ExposureMask);
/* May want this for a later refresh
XSelectInput(p->display, p->war,
ButtonPressMask|ButtonReleaseMask|ExposureMask);
*/
XSelectInput(p->display, p->warf, ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->warr, ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->wark, ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->waro, ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->wargo, ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->warno, ButtonPressMask|ButtonReleaseMask|ExposureMask);
XSelectInput(p->display, p->helpWin, ExposureMask);
XSelectInput(p->display, p->planetw, ExposureMask);
XSelectInput(p->display, p->playerw, ExposureMask);
}
setRedrawFlag()
{
if (skipUpdates)
doTheRedrawDude = 1;
else
doTheRedrawDude++;
}
deadpeer() {
fprintf(stderr, "SIGPIPE\n");
peerdied = 1;
}
int playerchange;
int nplayers;
int nrobots;
input()
{
register struct player *p;
register int pno;
XEvent data;
XEvent *tmp;
char buf[40];
char sbuf[40];
char new_display[50], new_login[50];
int nchar;
fd_set ofdset, fdset;
struct itimerval udt;
int didevent;
long elapsed;
int noplayer_updates;
struct sockaddr addr;
int addrlen;
int ns;
int on = 1;
int si;
signal(SIGALRM, setRedrawFlag);
udt.it_interval.tv_sec = 0L;
udt.it_interval.tv_usec = UPDATE;
udt.it_value.tv_sec = 0L;
udt.it_value.tv_usec = UPDATE;
setitimer(ITIMER_REAL, &udt, 0);
tmp = &data;
signal(SIGPIPE, SIG_DFL);
FD_ZERO(&ofdset);
FD_ZERO(&fdset);
playerchange = 1;
nplayers = 0;
nrobots = 0;
noplayer_updates = 0;
didevent = 1;
ns = -1;
while (1) {
if (ns < 0 && !nplayers && (noplayer_updates++ > (30 * UPS))) {
save_planets();
exit(0);
}
if (!didevent) {
fdset = ofdset;
pno = select(32, &fdset, (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) NULL);
if (pno < 0) {
FD_CLR(xtrek_socket, &fdset);
if (ns > 0)
FD_CLR(ns, &fdset);
}
}
if (FD_ISSET(xtrek_socket, &fdset) || (ns > 0 && FD_ISSET(ns, &fdset))) {
addrlen = sizeof (addr);
errno = 0;
if (ns == -1) {
ns = accept(xtrek_socket, &addr, &addrlen);
if (ns > 0) {
si = 0;
peerdied = 0;
signal(SIGPIPE, deadpeer);
ioctl(ns, FIONBIO, &on);
FD_SET(ns, &ofdset);
}
}
errno = 0;
if (ns > 0) {
pno = read(ns, &sbuf[si], 1);
if (pno > 0)
si += pno;
if (pno == 0)
peerdied = 1;
if (pno > 0 && si >= 2 && sbuf[si-2] == '\015' && sbuf[si-1] == '\012') {
sbuf[si-2] = '\0';
if (sscanf(sbuf, "Display: %s Login: %s", new_display, new_login) != 2) {
write(ns, "Bad format\n", 11);
close(ns);
ns = -1;
} else {
write(ns, "Creating connection on ", 23);
write(ns, new_display, strlen(new_display));
pno = findslot();
if (pno == MAXPLAYER) {
write(ns, "No more room in game\n", 21);
} else {
strcpy(players[pno].p_monitor, new_display);
strcpy(players[pno].p_login, new_login);
players[pno].p_status = PSETUP;
sprintf(sbuf, " as player number %d\n", pno);
write(ns, sbuf, strlen(sbuf));
}
}
playerchange = 1;
}
}
}
if (peerdied) {
peerdied = 0;
playerchange = 1;
}
if (playerchange) {
FD_ZERO(&ofdset);
FD_SET(xtrek_socket, &ofdset);
if (ns > 0)
FD_SET(ns, &ofdset);
nplayers = 0;
nrobots = 0;
signal(SIGPIPE, SIG_DFL);
for (pno = 0, p = &players[pno]; pno < MAXPLAYER; pno++, p++) {
if (p->p_status != PFREE) {
nplayers++;
if ((p->p_flags & PFROBOT) == 0) {
FD_SET(p->xcn, &ofdset);
} else
nrobots++;
}
}
if (nplayers)
noplayer_updates = 0;
playerchange = 0;
}
while (doTheRedrawDude-- > 0) {
intrupt();
}
didevent = 0;
for (pno = 0, p = &players[pno]; pno < MAXPLAYER; pno++, p++) {
if (p->p_status == PFREE)
continue;
if (p->p_status == PSETUP) {
char *rval;
playerchange = 1;
rval = newwin(p);
if (rval == (char *) NULL) /* Create new windows */
p->p_team = (FED|ROM|KLI|ORI); /* Team's they can pick from */
else {
write(ns, rval, strlen(rval));
write(ns, "\n", 1);
p->p_status = PFREE;
}
close(ns);
ns = -1;
if (p->p_status == POUTFIT)
mapAll(p); /* Map 'em... */
}
if (p->p_status == POUTFIT) {
if (!(p->p_flags & PFENTER)) {
p->p_flags |= PFENTER;
entrywindow(p); /* Show them the entry window */
} else {
elapsed = time(0) - p->startTime;
if (elapsed > AUTOQUIT) {
playerchange = 1;
XCloseDisplay(p->display);
p->display = (Display *) NULL;
p->p_status = PFREE;
p->p_flags &= ~PFENTER;
} else {
showTimeLeft(p, elapsed, AUTOQUIT, 0);
redrawFed(p, p->fwin, 0);
redrawRom(p, p->rwin, 0);
redrawKli(p, p->kwin, 0);
redrawOri(p, p->owin, 0);
}
}
}
if (!(FD_ISSET(p->xcn, &fdset)))
continue;
if (!XPending(p->display))
continue;
didevent = 1;
XNextEvent(p->display, (XEvent *)&data); /* grab the event */
if ((!(p->copilot /*|| watch*/)) && (p->p_updates > p->delay)) {
p->p_flags &= ~(PFWAR);
}
switch ((int) data.type) {
case KeyPress:
if (p->p_status == POUTFIT) {
int team;
team = -1;
if (data.xkey.window == p->fwin)
team = 0;
else if (data.xkey.window == p->rwin)
team = 1;
else if (data.xkey.window == p->kwin)
team = 2;
else if (data.xkey.window == p->owin)
team = 3;
else if (data.xkey.window == p->qwin) {
playerchange = 1;
XCloseDisplay(p->display);
p->display = (Display *) NULL;
p->p_status = PFREE;
p->p_flags &= ~PFENTER;
}
if (team >= 0) {
del_entrywindow(p);
XClearWindow(p->display, p->w);
p->p_flags &= ~PFENTER;
enter(team, XDisplayString(p->display), pno);
playerchange = 1;
}
continue;
}
if (inputIgnored(p))
continue;
if ((p->p_flags & PFSELFDEST) /*&& (!watch)*/) {
p->p_flags &= ~PFSELFDEST;
warning(p, "Self Destruct has been canceled");
}
nchar = XLookupString(&tmp->xkey, buf, sizeof buf,
(KeySym *)NULL, (XComposeStatus *)NULL);
if (nchar > 0) {
if (data.xkey.window == p->messagew)
smessage(p, *buf);
else
keyaction(p, *buf, &tmp->xkey);
}
break;
case ButtonPress:
if (p->p_status == POUTFIT) {
int team;
team = -1;
if (data.xkey.window == p->fwin)
team = 0;
else if (data.xkey.window == p->rwin)
team = 1;
else if (data.xkey.window == p->kwin)
team = 2;
else if (data.xkey.window == p->owin)
team = 3;
else if (data.xkey.window == p->qwin) {
playerchange = 1;
XCloseDisplay(p->display);
p->display = (Display *) NULL;
p->p_status = PFREE;
p->p_flags &= ~PFENTER;
}
if (team >= 0) {
del_entrywindow(p);
XClearWindow(p->display, p->w);
p->p_flags &= ~PFENTER;
enter(team, XDisplayString(p->display), pno);
playerchange = 1;
}
continue;
}
if (inputIgnored(p))
continue;
if ((p->p_flags & PFSELFDEST) /*&& (!watch)*/) {
p->p_flags &= ~PFSELFDEST;
warning(p, "Self Destruct has been canceled");
}
if (data.xbutton.window == p->warf)
waraction(p, &tmp->xbutton);
else if (data.xbutton.window == p->warr)
waraction(p, &tmp->xbutton);
else if (data.xbutton.window == p->wark)
waraction(p, &tmp->xbutton);
else if (data.xbutton.window == p->waro)
waraction(p, &tmp->xbutton);
else if (data.xbutton.window == p->wargo)
waraction(p, &tmp->xbutton);
else if (data.xbutton.window == p->warno)
waraction(p, &tmp->xbutton);
else
buttonaction(p, &tmp->xbutton);
break;
case Expose:
if (p->p_status == POUTFIT) {
if (data.xexpose.window == p->fwin)
redrawFed(p, p->fwin, 1);
else if (data.xexpose.window == p->rwin)
redrawRom(p, p->rwin, 1);
else if (data.xexpose.window == p->kwin)
redrawKli(p, p->kwin, 1);
else if (data.xexpose.window == p->owin)
redrawOri(p, p->owin, 1);
else if (data.xexpose.window == p->w)
showMotd(p);
else if (data.xexpose.window == p->qwin) {
redrawQuit(p, p->qwin);
elapsed = time(0) - p->startTime;
showTimeLeft(p, elapsed, AUTOQUIT, 1);
}
}
if (data.xexpose.window == p->statwin && (p->p_flags & PFSHOWSTATS))
redrawStats(p, p->statwin);
else if (data.xexpose.window == p->tstatw)
redrawTstats(p);
else if (data.xexpose.window == p->mapw)
p->redrawall = 1;
else if (data.xexpose.window == p->iconWin)
drawIcon(p);
else if (data.xexpose.window == p->helpWin)
fillhelp(p);
else if (data.xexpose.window == p->playerw)
playerlist(p);
else if (data.xexpose.window == p->planetw)
planetlist(p);
break;
default:
break;
} /* switch */
}
} /* (infinite) loop */
}
keyaction(p, key, data)
struct player *p;
char key;
XKeyEvent *data;
{
char buf[80];
unsigned char course;
struct obtype *gettarget(), *target;
struct player *p2;
struct planet *pl;
#ifdef notdef
if (watch && !index("LPSMiQ?hw ", key)) {
char buf[BUFSIZ];
sprintf(buf, "'%c' command is not permitted in watch mode.", key);
warning(buf);
return;
}
#endif
switch (key) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
set_speed(p, key - '0');
break;
case 'k': /* k = set course */
course = getcourse(p, data->window, data->x, data->y);
set_course(p, course);
p->p_flags &= ~(PFPLOCK | PFPLLOCK);
break;
case 'p': /* p = fire phasers */
course = getcourse(p, data->window, data->x, data->y);
phaser(p, course);
break;
case 't': /* t = launch torps */
course = getcourse(p, data->window, data->x, data->y);
ntorp(p, course, TMOVE);
break;
case 'd': /* d = detonate other torps */
detothers(p);
break;
case 'D': /* D = detonate my torps */
detmine(p);
break;
case '+': /* + = Put shields up */
shield_up(p);
break;
case '-': /* - = Put shields down */
shield_down(p);
break;
case 'u': /* u = toggle shields */
shield_tog(p);
break;
case 'b': /* b = bomb planet */
bomb_planet(p);
break;
case 'z': /* z = beam up */
beam_up(p);
break;
case 'x': /* x = beam down */
beam_down(p);
break;
case 'R': /* R = Go into repair mode */
p->p_flags &= ~(PFPLOCK | PFPLLOCK);
repair(p);
break;
case 'o': /* o = orbit nearest planet */
p->p_flags &= ~(PFPLOCK | PFPLLOCK);
orbit(p);
break;
case 'Q':
if (p->copilot /*|| watch*/)
exit(1);
p->p_flags |= PFSELFDEST;
p->selfdest = p->p_updates + PSELFDESTTIME;
warning(p, "Self destruct initiated");
break;
case '?': /* ? = Redisplay all messages */
repeat_message(p);
break;
case 'c': /* c = cloak */
cloak(p);
break;
case 'C': /* C = coups */
coup(p);
break;
case 'l': /* l = lock onto */
/* since a robot would never use this function (it's user
Interface dependent,) all the work is done here instead
of in interface.c */
target = gettarget(p, data->window, data->x, data->y,
TARG_PLAYER|TARG_PLANET);
if (target->o_type == PLAYERTYPE) {
p->p_flags |= PFPLOCK;
p->p_flags &= ~(PFPLLOCK|PFORBIT|PFBEAMUP|PFBEAMDOWN|PFBOMB);
p->p_playerl = target->o_num;
p2 = &players[target->o_num];
sprintf(buf, "Locking onto %s (%c%d)",
p2->p_name,
teamlet[p2->p_team],
p2->p_no);
warning(p, buf);
}
else { /* It's a planet */
p->p_flags |= PFPLLOCK;
p->p_flags &= ~(PFPLOCK|PFORBIT|PFBEAMUP|PFBEAMDOWN|PFBOMB);
p->p_planet = target->o_num;
pl = &planets[target->o_num];
sprintf(buf, "Locking onto %s",
pl->pl_name);
warning(p, buf);
}
break;
case '@': /* @ = toggle copilot permissions */
p->p_flags ^= PFCOPILOT;
break;
case '*': /* * = send in practice robot */
/* Only if no other players on OTHER teams. */
if (tcount[p->p_team] - (nplayers - nrobots) == 0)
startrobot(p->p_team, PFRHOSTILE);
break;
case '&': /* & = send in harder robot */
/* Only if no other players on OTHER teams. */
if (tcount[p->p_team] - (nplayers - nrobots) == 0)
startrobot(p->p_team, PFRHARD | PFRHOSTILE);
break;
/* Start of display functions */
case ' ': /* ' ' = clear special windows */
if (ismapped(p, p->playerw))
XUnmapWindow(p->display, p->playerw);
if (ismapped(p, p->planetw))
XUnmapWindow(p->display, p->planetw);
if (p->infomapped)
destroyInfo(p);
if (ismapped(p, p->war))
XUnmapWindow(p->display, p->war);
break;
case 'L': /* L = Player list */
if (ismapped(p, p->playerw)) {
XUnmapWindow(p->display, p->playerw);
} else {
XMapWindow(p->display, p->playerw);
}
break;
case 'P': /* P = Planet list */
if (ismapped(p, p->planetw)) {
XUnmapWindow(p->display, p->planetw);
} else {
XMapWindow(p->display, p->planetw);
}
break;
case 'S': /* S = Score list */
if (p->infomapped)
destroyInfo(p);
scorelist(p);
break;
case 's': /* s = toggle stat mode */
if (p->p_flags & PFSHOWSTATS) {
p->p_flags &= ~PFSHOWSTATS;
closeStats(p, p->statwin);
} else {
p->statwin = openStats(p);
p->p_flags |= PFSHOWSTATS;
}
break;
case 'U': /* U = toggle show shields */
p->showShields = !p->showShields;
break;
case 'M': /* M = Toggle Map mode */
p->mapmode = !p->mapmode;
break;
case 'N': /* N = Toggle Name mode */
p->namemode = !p->namemode;
break;
case 'i': /* i = get information */
if (!p->infomapped)
inform(p, data->window, data->x, data->y);
else
destroyInfo(p);
break;
case 'h': /* h = Map help window */
if (ismapped(p, p->helpWin)) {
XUnmapWindow(p->display, p->helpWin);
} else {
XMapWindow(p->display, p->helpWin);
}
break;
case 'w': /* w = map war stuff */
if (p->copilot) {
warning(p, "Copilots cannot alter war settings");
break;
}
if (ismapped(p, p->war)) {
XUnmapWindow(p->display, p->war);
p->redrawall = 1;
} else
warwindow(p);
break;
default:
XBell(p->display, 0);
break;
}
}
buttonaction(p, data)
register struct player *p;
XButtonEvent *data;
{
unsigned char course;
#ifdef notdef
struct obtype *gettarget(), *target;
if (watch) { /* Special case */
target = gettarget(data->window, data->x, data->y,
TARG_PLAYER|TARG_CLOAK);
setwatch(target->o_num);
return;
}
#endif
if ((data->button & Button3) == Button3) {
course = getcourse(p, data->window, data->x, data->y);
p->p_desdir = course;
p->p_flags &= ~(PFPLOCK | PFPLLOCK);
}
else if ((data->button & Button1) == Button1) {
course = getcourse(p, data->window, data->x, data->y);
ntorp(p, course, TMOVE);
}
else if ((data->button & Button2) == Button2) {
course = getcourse(p, data->window, data->x, data->y);
phaser(p, course);
}
}
getcourse(p, ww, x, y)
register struct player *p;
Window ww;
int x, y;
{
if (ww == p->mapw) {
int me_x, me_y;
me_x = p->p_x * WINSIDE / GWIDTH;
me_y = p->p_y * WINSIDE / GWIDTH;
return((unsigned char) (atan2((double) (x - me_x),
(double) (me_y - y)) / 3.14159 * 128.));
}
else
return((unsigned char) (atan2((double) (x - WINSIDE/2),
(double) (WINSIDE/2 - y))
/ 3.14159 * 128.));
}
inputIgnored(p)
register struct player *p;
{
#ifdef notdef
if (watch)
return(0);
#endif
if (p->p_status != PALIVE)
return (1);
if (p->p_flags & PFWAR) {
warning(p, "Battle computers being re-programmed");
return (1);
}
return (0);
}
setwatch(pno)
int pno;
{
register struct player *p;
p = &players[pno];
p->lastm = mctl->mc_current;
p->redrawall = 1;
if (p->p_flags & PFSHOWSTATS) {
closeStats(p, p->statwin);
p->statwin = openStats(p);
}
}