diff input.c @ 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/input.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1199 @@
+/* $Id: input.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * input.c
+ *
+ * Modified to work as client in socket based protocol
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <sys/types.h>
+#ifdef RS6K
+#include <sys/select.h>
+#endif
+#ifdef hpux
+#include <time.h>
+#else				/* hpux */
+#include <sys/time.h>
+#endif				/* hpux */
+#include <signal.h>
+#include <errno.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+
+#define control(x) (x)+128
+
+/* Prototypes */
+static void buttonaction P((W_Event * data));
+static void keyaction P((W_Event * data));
+static void scan P((W_Window w, int x, int y));
+/*static void selectblkbozo P((W_Event *data));*/
+
+static int tmodeChange = 0;	/* handles first change of tmode; including */
+				/* when a play first joins a tmode game */
+
+void
+initinput()
+{
+    /* Nothing doing... */
+}
+
+void
+dispatch_W_key_event(evt)
+    W_Event *evt;
+{
+    int     i;
+
+    /* try to speed up response -JR */
+    if (!messageon && (evt->Window == w || evt->Window == mapw)) {
+	keyaction(evt);
+	return;
+    }
+    for (i = 0; i < WNUM; i++) {
+	if (evt->Window == messWin[i].window) {
+	    messageWinEvent(evt);
+	    return;
+	}
+    }
+    if (evt->Window == optionWin)
+	optionaction(evt);
+    else if (
+#ifdef NOWARP
+	     messageon ||
+#endif
+	     evt->Window == messagew ||
+	     evt->Window == tstatw ||
+	     evt->Window == warnw) {
+	smessage(evt->key);
+#ifdef SHORT_PACKETS
+    } else if (evt->Window == spWin) {
+	spaction(evt);
+#endif
+    } else if (evt->Window == motdWin) {
+	motdWinEvent(evt->key);
+    } else if (evt->Window == playerw) {
+	playerwEvent(evt);
+    } else if (evt->Window == defWin && evt->key == ' ') {
+	W_UnmapWindow(defWin);
+#ifdef SOUND
+    } else if (evt->Window == soundWin) {
+	soundaction(evt);
+#endif
+#ifdef TOOLS
+    } else if (evt->Window == toolsWin) {
+	smessage_ahead('!', evt->key);
+#endif
+    } else {
+	keyaction(evt);
+    }
+}
+
+void
+dispatch_W_button_event(evt)
+    W_Event *evt;
+{
+    int     i;
+
+    if (evt->Window == w || evt->Window == mapw) {
+	buttonaction(evt);
+	return;
+    }
+    for (i = 0; i < WNUM; i++) {
+	if (evt->Window == messWin[i].window) {
+	    messageWinEvent(evt);
+	    return;
+	}
+    }
+    if (evt->Window == war)
+	waraction(evt);
+    else if (evt->Window == optionWin)
+	optionaction(evt);
+#ifdef ATM
+    else if (evt->Window == udpWin)
+	udpaction(evt);		/* UDP */
+#endif				/* ATM */
+#ifdef SHORT_PACKETS
+    else if (evt->Window == spWin)
+	spaction(evt);
+#endif
+#ifdef SOUND
+    else if (evt->Window == soundWin)
+	soundaction(evt);
+#endif
+    else if (evt->Window == playerw)
+	selectblkbozo(evt);
+#ifdef MACROS
+    else if (evt->Window == macroWin)
+	switchmacros();
+#endif
+#ifdef XTREKRC_HELP
+    else if (evt->Window == defWin)
+	def_action(evt);
+#endif
+    else
+	buttonaction(evt);
+}
+
+void
+dispatch_W_expose_event(evt)
+    W_Event *evt;
+{
+    /*
+       if anything but the iconWin is refreshed, turn off the iconified flag.
+       [BDyess]
+    */
+    if (evt->Window != iconWin)
+	iconified = 0;
+    if (evt->Window == statwin)
+	redrawStats();
+    else if (evt->Window == tstatw)
+	redrawTstats();
+    else if (evt->Window == mapw)
+	redrawall = 1;
+    else if (evt->Window == iconWin)
+	drawIcon();
+    else if (evt->Window == helpWin)
+	fillhelp();
+    else if (evt->Window == macroWin)
+	fillmacro();
+    else if (evt->Window == playerw)
+	playerlist();
+    else if (evt->Window == planetw)
+	planetlist();
+    else if (evt->Window == planetw2)
+	planetlist();
+    else if (evt->Window == rankw)
+	ranklist();
+    else if (evt->Window == warnw)
+	W_ClearWindow(warnw);
+    else if (evt->Window == messagew)
+	message_expose();
+    else if (evt->Window == motdWin)
+	motdWinEvent('r');	/* 'r' is refresh */
+    /*
+       lag meter?  maybe later - RF else if (evt->Window == lMeter)
+       redrawLMeter();
+    */
+    else if (evt->Window == pStats)
+	redrawPStats();
+#ifdef XTREKRC_HELP
+    else if (defWin && (evt->Window == defWin))
+	showdef();
+#endif
+}
+
+void
+dispatch_W_event(evt)
+    W_Event *evt;
+{
+    switch ((int) evt->type) {
+    case W_EV_KEY:
+	dispatch_W_key_event(evt);
+	break;
+#ifdef AUTOKEY
+    case W_EV_KEY_OFF:
+	if (autoKey)
+	    autoKeyOff(evt);
+	break;
+#endif				/* AUTOKEY */
+    case W_EV_BUTTON:
+	dispatch_W_button_event(evt);
+	break;
+    case W_EV_EXPOSE:
+	dispatch_W_expose_event(evt);
+	break;
+    default:
+	break;
+    }
+}
+
+/* this figures out what to set war dec's */
+void autoWarDecl(scheme)
+     int scheme;
+{
+     extern int number_of_teams;
+     int i, j, k, *team, enemymask = 0;
+     struct player *pptr;
+
+     if((team = (int *)malloc(number_of_teams * sizeof(int))) == NULL) {
+        perror("autoWarDecl: malloc error\n");
+        return;
+     }
+     memset(team, 0, sizeof(int)*number_of_teams);
+     for(i=0, pptr=&players[i]; i < nplayers; i++, pptr++)
+        if(pptr->p_status != PFREE && !(pptr->p_status == POUTFIT &&
+                                     pptr->p_teami < 0)) {
+             team[pptr->p_teami]++;
+        }
+     switch(scheme) {
+     case 1:
+        /* war with all non-zero member team */
+        /* peace with teams with 0 players */
+        for(i=0; i < number_of_teams; i++) {
+             if(i != me->p_teami)
+                  enemymask ^= team[i] ? (1<<i) : 0;
+             /*printf("team: %i, #: %i\n", i, team[i]);
+              */
+        }
+        /*printf("mask: %i\n", enemymask);
+         */
+        break;
+     case 2:
+        /* war with only the largest enemy */
+        /* team; peace with everyone else*/
+        for(i=0; i < number_of_teams; i++) {
+             if ((i != me->p_teami) && (j < team[i])) {
+                  j = team[i];
+                  k = i;
+             }
+        }
+        enemymask = 0 | (1 << k);
+        break;
+     }
+     sendWarReq(enemymask);
+     free(team);
+} /* end of autoWarDecl */
+
+
+/* this new event loop allows more flexibility in state transitions */
+void
+input()
+{
+    W_Event data;
+    fd_set  readfds;
+    int     wsock = W_Socket();
+    int     old_tourn = paradise ? status2->tourn : status->tourn, new_tourn;
+
+#ifdef AUTOKEY
+    struct timeval timeout;
+
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 100000;
+#endif				/* AUTOKEY */
+
+#ifdef RECORDER
+    if (playback) {
+	pb_input(); /* recorder.c */
+	return;
+    }
+#endif
+    while (me->p_status == PALIVE ||
+	   me->p_status == PEXPLODE ||
+	   me->p_status == PDEAD ||
+	   me->p_status == POBSERVE) {
+
+#ifdef TIMELORD
+	/* we're playing.  Count the seconds */
+	update_timelord(0);
+#endif
+
+	if (keepInfo > 0) {
+	    if (infowin_up >= 0 &&
+		--infowin_up == -1 &&
+		infomapped) {
+		destroyInfo();
+		infowin_up = -2;
+	    }
+	}
+	exitInputLoop = 0;
+	while (W_EventsPending() && !exitInputLoop) {
+	    fastQuit = 0;	/* any event cancel fastquit */
+	    W_NextEvent(&data);
+	    dispatch_W_event(&data);
+	}
+
+#if 0
+	/*
+	   Do some enforcement of non-paradise feature disabling. The options
+	   menu doesn't deal with this too well.
+	*/
+	if (!paradise) {
+	    blk_zoom = 0;
+	    blk_showStars = 0;
+	}
+#endif
+#ifndef AMIGA
+	FD_ZERO(&readfds);
+	FD_SET(wsock, &readfds);
+	FD_SET(sock, &readfds);
+	if (udpSock >= 0)
+	    FD_SET(udpSock, &readfds);
+#ifdef AUTOKEY
+	    if (autoKey) {
+		doAutoKey();
+		if (select(32, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout) == 0)	/* timeout */
+		    continue;
+	    } else
+#endif
+		select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
+#else				/* AMIGA */
+#ifdef DNET
+	sigsPending = Wait(wsock | sockMask | udpSockMask | SIGBREAKF_CTRL_C);
+#else
+/* insert code here for Amiga with TCP/IP... */
+#endif				/* DNET */
+	if (sigsPending & SIGBREAKF_CTRL_C) {
+	    printf("User break, Ctrl-C, exiting!\n");
+	    exit(0);
+	}
+/* note: for DNET, FD_ISSET is faked, see amigadefs.h -JR */
+#endif				/* AMIGA */
+	if (FD_ISSET(sock, &readfds) ||
+	    (udpSock >= 0 && FD_ISSET(udpSock, &readfds))) {
+	    
+#ifdef HANDLER_TIMES
+	    start_log();
+#endif
+	    intrupt();
+#ifdef HANDLER_TIMES
+	    stop_log(64);
+#endif
+	    if (isServerDead()) {
+		printf("Whoops!  We've been ghostbusted!\n");
+		printf("Pray for a miracle!\n");
+		
+		/* UDP fail-safe */
+		commMode = commModeReq = COMM_TCP;
+		commSwitchTimeout = 0;
+		if (udpSock >= 0)
+		    closeUdpConn();
+		if (udpWin) {
+		    udprefresh(UDP_CURRENT);
+		    udprefresh(UDP_STATUS);
+		}
+		connectToServer(nextSocket);
+		printf("Yea!  We've been resurrected!\n");
+	    }
+	    /*
+	       beep if tmode status changes.  Idea from Roger Books. [BDyess]
+	    */
+	    new_tourn = paradise ? status2->tourn : status->tourn;
+
+	    /* change war dec's at transitions to */
+	    /* positive tmode */
+	    if (!tmodeChange && new_tourn) {
+		 autoWarDecl(autoSetWar);
+		 tmodeChange = 1;
+	    }
+
+	    if (old_tourn != new_tourn) {
+#ifndef SOUND
+		W_Beep();
+#else
+		S_PlaySound(S_TMODE);
+#endif
+		old_tourn = new_tourn;
+	    }
+	    continue;
+	}
+    }
+}
+
+
+static void
+keyaction(data)
+    W_Event *data;
+{
+    unsigned char course;
+    struct obtype *target;
+    int     key = data->key;
+    struct shiplist *temp;
+
+    if (data->Window != mapw && data->Window != w
+	&& data->Window != planetw && data->Window != planetw2
+	&& data->Window != rankw
+#ifdef ATM
+	&& data->Window != scanw
+#endif				/* ATM */
+	)
+	return;
+
+#ifdef RECORDER
+    if (playback)
+	pb_dokey(data);
+#endif
+    if (localflags & PFREFIT) {
+	temp = shiptypes;
+	while (temp) {
+	    if (temp->ship->s_letter == key) {
+		do_refit(temp->ship->s_type);
+		return;
+	    }
+	    temp = temp->next;
+	}
+    } else {
+	key = doKeymap(data);
+	if (key == -1)
+	    return;
+    }
+
+    switch (key) {
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	set_speed(key - '0');
+	localflags &= ~(PFREFIT);
+	break;
+    case 'e':			/* Turn off docking permission, eject docked
+				   vessels. */
+	sendDockingReq(!(me->p_flags & PFDOCKOK));
+	break;
+    case 'r':
+	localflags |= PFREFIT;
+	warning(blk_refitstring);
+	break;
+    case control('0'):		/* ctrl 0-9, speed 10-19 */
+    case control('1'):
+    case control('2'):
+    case control('3'):
+    case control('4'):
+    case control('5'):
+    case control('6'):
+    case control('7'):
+    case control('8'):
+    case control('9'):
+	set_speed(10 + key - control('0'));
+	localflags &= ~(PFREFIT);
+	break;
+    case control(')'):		/* ctrl-shift 0-9, speed 20-29 */
+	set_speed(20);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('!'):		/* ctrl-shift-1, speed 21 */
+	set_speed(21);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('@'):		/* ctrl-shift-2, speed 22 */
+	set_speed(22);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('#'):		/* ctrl-shift-3, speed 23 */
+	set_speed(23);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('$'):		/* ctrl-shift-4, speed 24 */
+	set_speed(24);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('%'):		/* ctrl-shift-5, speed 25 */
+	set_speed(25);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('^'):		/* ctrl-shift-6, speed 26 */
+	set_speed(26);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('&'):		/* ctrl-shift-7, speed 27 */
+	set_speed(27);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('*'):		/* ctrl-shift-8, speed 28 */
+	set_speed(28);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('('):		/* ctrl-shift-9, speed 29 */
+	set_speed(29);
+	localflags &= ~(PFREFIT);
+	break;
+    case '`':			/* afterburners */
+	set_speed(98);
+	localflags &= ~(PFREFIT);
+	break;
+    case '-':
+	set_speed(99);		/* warp! */
+	localflags &= ~(PFREFIT);
+	break;
+    case control('-'):		/* suspend warp toggle [BDyess] */
+	if (me->p_flags & PFWPSUSPENDED)
+	    set_speed(96);	/* unsuspend */
+	else
+	    set_speed(97);	/* suspend */
+	localflags &= ~(PFREFIT);
+	break;
+    case '%':			/* max impulse */
+	set_speed(me->p_ship->s_maxspeed);
+	localflags &= ~(PFREFIT);
+	break;
+    case '<':			/* speed -= 1 */
+	set_speed(me->p_speed - 1);
+	localflags &= ~(PFREFIT);
+	break;
+    case '>':			/* speed += 1 */
+	set_speed(me->p_speed + 1);
+	localflags &= ~(PFREFIT);
+	break;
+    case '#':			/* halfimpulse */
+	set_speed((me->p_ship->s_maxspeed + 1) / 2);
+	localflags &= ~(PFREFIT);
+	break;
+    case ':':			/* toggle message logging */
+	if (logmess)
+	    warning("Message logging disabled");
+	else
+	    warning("Message logging enabled");
+	logmess = !logmess;
+	break;
+    case '!':
+#if 1
+	showKitchenSink = !showKitchenSink;
+	warning(showKitchenSink ?
+		"Kitchen Sink activated.  Bad guys beware!" :
+		"Kitchen Sink deactivated.");
+#else
+	if (blk_altbits) {
+	    blk_altbits = 0;
+	    warning("Switching to old bitmaps.");
+	} else {
+	    blk_altbits = 1;
+	    warning("Switching to new bitmaps.");
+	}
+	localflags &= ~(PFREFIT);
+	if (optionWin)
+	    optionredrawoption(&blk_altbits);
+#endif
+	break;
+#ifdef TIMER
+    case '@':
+	timeBank[T_USR] = time(NULL);
+	timerType = T_USR;
+	break;
+    case control('t'):
+	timerType++;
+	if (timerType >= T_TOTAL)
+	    timerType = 0;
+	break;
+#endif				/* TIMER */
+#ifdef WIDE_PLIST
+    case 'K':			/* cycle playerlist [BDyess] */
+	while (*playerList && *playerList != ',')
+	    playerList++;
+	if (*playerList == ',')
+	    playerList++;
+	else if (*playerList == 0)
+	    playerList = playerListStart;
+	break;
+#endif				/* WIDE_PLIST */
+    case 'a':
+#ifdef ATM
+	if (!W_IsMapped(scanwin)) {
+	    scan(data->Window, data->x, data->y);
+	} else {
+	    if (scanmapped)
+		W_UnmapWindow(scanwin);
+	    scanmapped = 0;
+	}
+#endif				/* ATM */
+	break;
+    case 'm':			/* new from galaxy -- works here too */
+    case '\'':           /* ' starts message to 'T'eam */
+#ifdef NOWARP
+	message_on();
+#else
+	W_WarpPointer(messagew);
+#endif
+	if((key == '\'') && (messpend==0)) {
+	    smessage(lowercaset ? 't' : 'T');
+	}
+	break;
+    case 'k':			/* k = set course */
+	course = getcourse(data->Window, data->x, data->y);
+	set_course(course);
+	me->p_flags &= ~(PFPLOCK | PFPLLOCK);
+	localflags &= ~(PFREFIT);
+	break;
+    case 'p':			/* p = fire phasers */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyPhaserReqOn();
+	else {
+	    course = getcourse(data->Window, data->x, data->y);
+	    sendPhaserReq(course);
+	}
+#else
+	course = getcourse(data->Window, data->x, data->y);
+	sendPhaserReq(course);
+#endif				/* AUTOKEY */
+	break;
+    case 't':			/* t = launch torps */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyTorpReqOn();
+	else {
+	    course = getcourse(data->Window, data->x, data->y);
+	    sendTorpReq(course);
+	}
+#else
+	course = getcourse(data->Window, data->x, data->y);
+	sendTorpReq(course);
+#endif				/* AUTOKEY */
+	break;
+    case 'f':
+	/* f = launch plasma torpedos */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyPlasmaReqOn();
+	else {
+	    course = getcourse(data->Window, data->x, data->y);
+	    sendPlasmaReq(course);
+	}
+#else
+	course = getcourse(data->Window, data->x, data->y);
+	sendPlasmaReq(course);
+#endif				/* AUTOKEY */
+	break;
+    case 'd':			/* d = detonate other torps */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyDetReqOn();
+	else
+	    sendDetonateReq();
+#else
+	sendDetonateReq();
+#endif				/* AUTOKEY */
+	break;
+    case 'D':			/* D = detonate my torps */
+	detmine();
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyAllOff();	/* xx */
+#endif
+	break;
+    case '[':
+	shield_down();
+	break;
+    case ']':
+	shield_up();
+	break;
+    case 'u':			/* u = toggle shields */
+	shield_tog();
+	break;
+    case 's':			/* For Serge */
+	shield_tog();
+	break;
+    case 'b':			/* b = bomb planet */
+#ifdef AUTOKEY
+	if (autoKey && !(localflags & PFREFIT))
+	    autoKeyBombReqOn();
+	else
+	    bomb_planet();
+#else
+	bomb_planet();
+#endif				/* AUTOKEY */
+	break;
+    case 'z':			/* z = beam up */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyBeamUpReqOn();
+	else
+#endif
+	    beam_up();
+	break;
+    case 'x':			/* x = beam down */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyBeamDownReqOn();
+	else
+#endif
+	    beam_down();
+	break;
+    case 'X':			/* X = enter macro mode */
+	macroState = 1;
+	warning("Macro mode");
+	break;
+    case 'R':			/* R = Go into repair mode */
+	sendRepairReq(1);
+	break;
+    case 'y':
+    case 'T':
+    case '_':			/* _ = turn on tractor beam */
+    case '^':			/* ^ = turn on pressor beam */
+	if (me->p_flags & (PFTRACT | PFPRESS)) {
+	    sendTractorReq(0, me->p_no);
+	    if (key == 'T' || key == 'y')
+		break;
+	}
+	target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+	me->p_tractor = target->o_num;
+	if (key == 'T' || key == '_') {
+	    sendTractorReq(1, target->o_num);
+	} else {
+	    sendRepressReq(1, target->o_num);
+	}
+	break;
+    case '$':			/* turn off tractor/pressor beam */
+	sendTractorReq(0, me->p_no);
+	break;
+    case 'o':			/* o = dock at nearby starbase or orbit
+				   nearest planet */
+#ifdef AUTOKEY
+	if (autoKey && !(localflags & PFREFIT))
+	    autoKeyOrbitReqOn();
+	else
+	    sendOrbitReq(1);
+#else
+	sendOrbitReq(1);
+#endif				/* AUTOKEY */
+	break;
+    case 'O':			/* O = options Window */
+	if (optionWin != NULL && W_IsMapped(optionWin))
+	    optiondone();
+	else
+	    optionwindow();
+	break;
+    case 'Q':
+	sendQuitReq();
+	break;
+    case 'q':			/* fastquit */
+	fastQuit = 1;
+	sendQuitReq();
+	break;
+    case 'V':
+	{
+	    /* configurable showlocal rotation sequence [BDyess] */
+	    int     i, len = strlen(showLocalSequence);
+	    for (i = 0; i < len; i++) {
+		if (showLocalSequence[i] - '0' == showlocal) {
+		    showlocal = showLocalSequence[(i + 1) % len] - '0';
+		    break;
+		}
+	    }
+	    if (i == len)
+		showlocal = (*showLocalSequence) - '0';
+	    if (showlocal > 4)
+		showlocal = 4;
+	    else if (showlocal < 0)
+		showlocal = 0;
+	}
+	if (optionWin)
+	    optionredrawoption(&showlocal);
+	break;
+    case 'B':
+	{
+	    /* configurable showgalactic rotation sequence [BDyess] */
+	    int     i, len = strlen(showGalacticSequence);
+	    for (i = 0; i < len; i++) {
+		if (showGalacticSequence[i] - '0' == showgalactic) {
+		    showgalactic = showGalacticSequence[(i + 1) % len] - '0';
+		    break;
+		}
+	    }
+	    if (i == len)
+		showgalactic = (*showGalacticSequence) - '0';
+	    if (!paradise && showgalactic == 3)
+		showgalactic = 5;	/* force scout ages -> MOO */
+	    if (showgalactic > 5)
+		showgalactic = 5;
+	    else if (showgalactic < 0)
+		showgalactic = 0;
+	}
+	redrawall = 1;
+	if (optionWin)
+	    optionredrawoption(&showgalactic);
+	break;
+    case '?':			/* ? = Redisplay all message windows */
+	if (!W_IsMapped(messWin[WREVIEW].window)) {
+	    if (W_IsMapped(messWin[WALL].window)) {
+		int     i;
+		for (i = 0; i < WNUM; i++) {
+		    if (W_IsMapped(messWin[i].window))
+			W_UnmapWindow(messWin[i].window);
+		}
+	    } else {
+		W_MapWindow(messWin[WREVIEW].window);
+	    }
+	} else {
+	    W_UnmapWindow(messWin[WREVIEW].window);
+	    W_MapWindow(messWin[WALL].window);
+	    W_MapWindow(messWin[WTEAM].window);
+	    W_MapWindow(messWin[WINDIV].window);
+	    W_MapWindow(messWin[WKILL].window);
+	    W_MapWindow(messWin[WPHASER].window);
+	}
+	if (optionWin) {
+	    optionredrawtarget(messWin[WREVIEW].window);
+	    optionredrawtarget(messWin[WALL].window);
+	    optionredrawtarget(messWin[WKILL].window);
+	    optionredrawtarget(messWin[WTEAM].window);
+	    optionredrawtarget(messWin[WINDIV].window);
+	    optionredrawtarget(messWin[WPHASER].window);
+	}
+	break;
+    case 'c':			/* c = cloak */
+	cloak();
+	break;
+    case '{':			/* { = cloak, no toggle */
+	sendCloakReq(1);
+	break;
+    case '}':			/* } = uncloak, no toggle */
+	sendCloakReq(0);
+	break;
+    case 'C':			/* C = coups */
+	sendCoupReq();
+	break;
+    case ';':			/* ; = lock onto planet/base */
+	target = gettarget(data->Window, data->x, data->y,
+			   TARG_BASE | TARG_PLANET);
+	if (target->o_type == PLAYERTYPE) {
+	    sendPlaylockReq(target->o_num);	/* a base */
+	    me->p_playerl = target->o_num;
+	} else {		/* It's a planet */
+	    sendPlanlockReq(target->o_num);
+	    me->p_planet = target->o_num;
+	}
+	break;
+    case 'l':			/* l = lock onto */
+	target = gettarget(data->Window, data->x, data->y,
+			   TARG_PLAYER | TARG_ASTRAL);
+	if (target->o_type == PLAYERTYPE) {
+	    sendPlaylockReq(target->o_num);
+	    me->p_playerl = target->o_num;
+	} else {		/* It's a planet */
+	    sendPlanlockReq(target->o_num);
+	    me->p_planet = target->o_num;
+	}
+	break;
+    case '/':			/* toggle sorted player list */
+	sortPlayers = !sortPlayers;
+	break;
+    case '*':			/* send in practice robot */
+	sendPractrReq();
+	break;
+	/* Start of display functions */
+    case ' ':			/* ' ' = clear special windows */
+	W_UnmapWindow(planetw);
+	W_UnmapWindow(planetw2);
+	W_UnmapWindow(rankw);
+	if (infomapped)
+	    destroyInfo();
+	W_UnmapWindow(helpWin);
+	W_UnmapWindow(war);
+	if (optionWin)
+	    optiondone();
+#ifdef ATM
+	if (scanmapped) {
+	    W_UnmapWindow(scanwin);
+	    scanmapped = 0;
+	}
+	if (udpWin)
+	    udpdone();
+#endif				/* ATM */
+#ifdef XTREKRC_HELP
+	if (defWin)
+	    W_UnmapWindow(defWin);
+#endif
+	break;
+    case 'E':			/* E = send emergency call */
+	if (F_gen_distress)
+	    rcd(generic, data);
+	else
+	    emergency();
+	break;
+    case 'F':			/* F = send carry report */
+	if (F_gen_distress)
+	    rcd(carrying, data);
+	else
+	    carry_report();
+	break;
+    case 'L':			/* L = Player list */
+	if (W_IsMapped(playerw)) {
+	    W_UnmapWindow(playerw);
+	} else {
+	    W_MapWindow(playerw);
+	}
+	break;
+    case 'P':			/* P = Planet list */
+	if (W_IsMapped(planetw)) {
+	    W_UnmapWindow(planetw);
+	    W_UnmapWindow(planetw2);
+	} else {
+	    W_MapWindow(planetw);
+	    W_MapWindow(planetw2);
+	}
+	break;
+    case 'U':			/* U = Rank list */
+	if (W_IsMapped(rankw)) {
+	    W_UnmapWindow(rankw);
+	} else {
+	    W_MapWindow(rankw);
+	}
+	break;
+    case 'S':			/* S = toggle stat mode */
+	if (W_IsMapped(statwin)) {
+	    W_UnmapWindow(statwin);
+	} else {
+	    W_MapWindow(statwin);
+	}
+	break;
+#ifdef nodef			/* people hit this by accident and think the
+				   client crashed */
+    case 'M':			/* M = Toggle Map mode */
+	mapmode = !mapmode;
+	if (optionWin)
+	    optionredrawoption(&mapmode);
+	break;
+#endif
+    case 'M':			/* map the motd window */
+	showMotdWin();
+	break;
+    case 'N':			/* N = Toggle Name mode */
+	namemode = !namemode;
+	if (optionWin)
+	    optionredrawoption(&namemode);
+	break;
+    case 'i':			/* i = get information */
+    case 'I':			/* I = get extended information */
+    case control('i'):		/* ^i = info on a planet [BDyess] */
+	if (!infomapped)
+	    inform(data->Window, data->x, data->y, key);
+	else
+	    destroyInfo();
+	break;
+    case 'h':			/* h = Map help window */
+	if (W_IsMapped(helpWin)) {
+	    W_UnmapWindow(helpWin);
+	} else {
+	    W_MapWindow(helpWin);
+	}
+	if (optionWin)
+	    optionredrawtarget(helpWin);
+	break;
+    case 'w':			/* w = map war stuff */
+	if (W_IsMapped(war))
+	    W_UnmapWindow(war);
+	else
+	    warwindow();
+	break;
+#ifdef ATM
+    case '+':			/* UDP: pop up UDP control window */
+	if (udpWin != NULL && W_IsMapped(udpWin))
+	    udpdone();
+	else {
+	    char    buf[80];
+	    udpwindow();
+	    sprintf(buf, "UDP client version %.1f",
+		    (float) UDPVERSION / 10.0);
+	    warning(buf);
+	}
+	if (optionWin)
+	    optionredrawtarget(udpWin);
+	break;
+    case '=':			/* UDP: request for full update */
+	sendUdpReq(COMM_UPDATE);
+	break;
+#endif				/* ATM */
+
+    case 9:			/* tab */
+    case control('m'):		/* because you can't remap to tab */
+	                        /* actually, you can, put a literal
+				   TAB in a ckeymap entry and it works.
+				   So should we keep this? -JR */
+	if(paradise) {
+	    blk_zoom = !blk_zoom;
+	    redrawall = 1;
+	    auto_zoom_timer = udcounter+autoZoomOverride;
+	    if (optionWin)
+		optionredrawoption(&blk_zoom);
+	}
+	break;
+#ifdef SHORT_PACKETS
+    case '~':
+	if (spWin != NULL && W_IsMapped(spWin))
+	    spdone();
+	else
+	    spwindow();
+	if (optionWin)
+	    optionredrawtarget(spWin);
+	break;
+    case '\\':
+	sendShortReq(SPK_SALL);
+	break;
+    case '|':
+	sendShortReq(SPK_ALL);
+	break;
+#endif
+    case ',':
+	if (W_IsMapped(pStats)) {
+	    W_UnmapWindow(pStats);
+	} else {
+	    W_MapWindow(pStats);
+	    redrawPStats();
+	}
+	if (optionWin)
+	    optionredrawtarget(pStats);
+	break;
+    case '&':			/* reread defaults file */
+	if (defaultsFile) {
+	    char    buf[150];
+	    sprintf(buf, "Reading defaults from %s", defaultsFile);
+	    warning(buf);
+	    freeDefaults();
+	    defaultsFile = initDefaults(defaultsFile);
+	    resetDefaults();
+	} else {
+	    warning("No defaults file to read from!");
+	}
+	break;
+#ifdef ROTATERACE
+    case '(':
+	rotate--;
+	if (rotate < 0)
+	    rotate = 3;
+	if (optionWin)
+	    optionredrawoption(&rotate);
+	rotate_all();
+	break;
+    case ')':
+	rotate++;
+	if (rotate > 3)
+	    rotate = 0;
+	if (optionWin)
+	    optionredrawoption(&rotate);
+	rotate_all();
+	break;
+#endif
+
+#ifdef RECORDER
+    case control('r'):
+	stopRecorder();
+	break;
+#endif
+
+#ifdef SOUND
+    case control('s'):
+	S_SoundWindow();
+	break;
+#endif
+#ifdef TOOLS
+    case '\"':
+	showToolsWin();
+	break;
+#endif
+#ifdef AMIGA
+    case 'A':
+	{
+	    extern int flush_speech;
+	    flush_speech = 1;
+	    break;
+	}
+#endif				/* AMIGA */
+    default:
+	W_Beep();
+	break;
+    }
+}
+
+static void
+buttonaction(data)
+    W_Event *data;
+{
+    unsigned char course;
+
+#ifdef NOWARP
+    if (messageon)
+	message_off();		/* ATM */
+#endif
+
+    if (data->Window != w && data->Window != mapw
+#ifdef ATM
+	&& data->Window != scanwin
+#endif				/* ATM */
+	)
+	return;
+
+    data->key--;
+    if (data->key >= 0 && data->key < 12) {
+	if (myship->s_buttonmap[data->key] != '\0') {
+	    data->key = myship->s_buttonmap[data->key];
+#if 0				/* do NOT bypass keymap */
+	    data->key += 256;	/* simulate alt key so keymap is bypassed
+				   [BDyess] */
+#endif
+	    keyaction(data);
+	    return;
+	} else
+	    data->key = data->key % 3;
+	/* if alt key is pressed, do default */
+    } if (data->key > 11)
+	data->key -= 12;
+    data->key++;
+    if (data->key == W_RBUTTON) {
+	course = getcourse(data->Window, data->x, data->y);
+	set_course(course);
+    } else if (data->key == W_LBUTTON) {
+	course = getcourse(data->Window, data->x, data->y);
+	sendTorpReq(course);
+    } else if (data->key == W_MBUTTON) {
+	course = getcourse(data->Window, data->x, data->y);
+	sendPhaserReq(course);
+    }
+}
+
+/*
+ * changed from unsigned char to irint() for precise rounding (from Leonard
+ * Dickens)
+ *
+ *  changed from irint (which ULTRIX doesn't have in its math.h header) to
+ * floor(x+0.5) for portability.
+ */
+
+
+
+int
+getcourse(ww, x, y)
+    W_Window ww;
+    int     x, y;
+{
+    if (ww == mapw) {
+	int     me_x, me_y;
+	register gwidth, offsetx, offsety;
+
+	if (blk_zoom) {
+	    gwidth = blk_gwidth / 2;
+	    offsetx = zoom_offset(me->p_x);
+	    offsety = zoom_offset(me->p_y);
+	} else {
+	    gwidth = blk_gwidth;
+	    offsetx = 0;
+	    offsety = 0;
+	}
+	me_x = (me->p_x - offsetx) * WINSIDE / gwidth;
+	me_y = (me->p_y - offsety) * WINSIDE / gwidth;
+
+	return (unsigned char)(int)
+	  floor(0.5 + atan2((double) (x - me_x),
+			    (double) (me_y - y))
+		         / 3.14159 * 128.);
+
+
+    } else {
+
+      double	result = atan2((double) (x - WINSIDE / 2),
+			       (double) (WINSIDE / 2 - y)) / 3.14159 * 128.;
+
+      return (unsigned char) (int) floor (result + 0.5);
+    }
+}
+#ifdef ATM
+static void
+scan(w, x, y)
+    W_Window w;
+    int     x, y;
+{
+}
+#endif				/* ATM */