DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T i

⟦8f8130206⟧ TextFile

    Length: 17920 (0x4600)
    Types: TextFile
    Names: »input.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/X/Xtrek/input.c« 

TextFile

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);
    }
}