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