view 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 source

/* $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 */