diff option.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/option.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1029 @@
+/* $Id: option.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * option.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include "Wlib.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+
+#ifdef DEBUG
+#define IFDEBUG(foo)    foo
+#else
+#define IFDEBUG(foo)
+#endif
+
+static int notdone;		/* not done flag */
+static int oldzoom = -2;
+
+/* kludgy way to make options that do some action when clicked: */
+static int clearPhaserStats = 1;
+static int reloadShipBitmaps = 1;
+
+#ifdef ROTATERACE
+static int old_rotate, old_rotate_deg;
+#endif
+
+static int old_ping;
+
+/* static int updateSpeed= 5;*/
+static int lastUpdateSpeed = -1;
+
+static char newkeys[14];
+static char newckeys[14];
+static char newbuttons[14];
+static char newcbuttons[14];
+
+static int remapAllShips = 1;
+
+char *keymapmes[] = {
+    "Key/Buttonmap only affect THIS ship type",
+    "Key/Buttonmap affect ALL ship types",
+    ""
+};
+
+#ifdef TIMER
+char   *timermes[] =
+{"Timer shows nothing (off)",
+    "Timer shows time of day",
+    "Timer shows time on server",
+    "Timer shows time in ship",
+    "Timer shows user-set time",
+""};
+#endif				/* TIMER */
+
+char   *localmes[] =
+{"Show owner on local planets",
+    "Show facilities on local planets",
+    "Show nothing on local planets",
+    "Show surface properties on local planets",
+    "Show MOO facilities on local planets",
+""};
+
+char   *galacticmes[] =
+{"Show owner on galactic map",
+    "Show facilities on galactic map",
+    "Show nothing on galactic map",
+    "Show surface properties on galactic map",
+    "Show scout info age on galactic map",
+    "Show MOO facilities on galactic map",
+""};
+
+#ifdef ROTATERACE
+char   *rotatemess[] =
+{"Don't rotate galaxy",
+    "Rotate galaxy 90 degrees",
+    "Rotate galaxy 180 degrees",
+    "Rotate galaxy 270 degrees",
+    ""
+};
+#endif
+
+char   *mapupdates[] =
+{"Don't update galactic map",
+    "Update galactic map frequently",
+    "Update galactic map rarely",
+""};
+
+static char *lockoptions[] =
+{"Don't show lock icon",
+    "show lock icon on galactic map only",
+    "Show lock icon on tactical map only",
+"Show lock icon on both map windows", ""};
+
+static char *phaseroptions[] =
+{"Don't show phaser messages",
+    "Phaser messages in kill window",
+    "Phaser messages in phaser window",
+    "Phaser messages in phaser window only",
+    "Phaser messages in total review only",
+""};
+
+static char *dashboardoptions[] =
+{"Old Dashboard",
+    "New Dashboard",
+    "Color Dashboard",
+    "Rainbow Dashboard",
+""};
+
+static char *autoZoomOpts[] =
+{"Don't auto-zoom map",
+     "Auto-zoom map on Red OR Yellow Alert",
+     "Auto-zoom map on Red Alert",
+""};
+
+static char *autoUnZoomOpts[] =
+{"Don't auto-unzoom map",
+     "Auto-unzoom map on Green alert",
+     "Auto-unzoom map on Green OR Yellow Alert",
+""};
+
+static char *autoSetWarOpts[] = 
+{"Don't auto set war declarations",
+	"Set war with non-zero player teams",
+	"Set war with largest enemy team",
+""};
+
+/* useful for options that are an int with a range */
+struct int_range {
+    int     min_value;		/* value is >= this */
+    int     max_value;		/* value is <= this */
+    int     increment;		/* a click raises/lowers this amount */
+				/* do bitwise shift by 1 if increment */
+				/* == -1 */
+};
+
+
+/*
+ * Only one of op_option, op_targetwin, and op_string should be defined. If
+ * op_string is defined, op_size should be too and op_text is used without a
+ * "Don't" prefix. if op_range is defined, there should be a %d in op_text
+ * for it, op_size will be non-useful, and the 'Don't ' prefix won't appear
+ */
+struct option {
+    char   *op_text;		/* text to display when on */
+    int    *op_option;		/* variable to test/modify (optional) */
+    W_Window *op_targetwin;	/* target window to map/unmap (optional) */
+    char   *op_string;		/* string to modify (optional) */
+    int     op_size;		/* size of *op_string (optional) */
+    char  **op_array;		/* array of strings to switch between */
+    struct int_range *op_range;	/* struct definint an integer range option */
+
+    int     op_num;		/* used internally */
+};
+
+/* for the paged options menus */
+struct option_menu {
+    int     page_num;		/* page number of this menu */
+    struct option_menu *Next;
+    struct option *menu;	/* pointers to arrary of options */
+    int     numopt;		/* number of options in this menu page */
+    int     updated;		/* 1 if options can be changed externally */
+};
+
+/* pointer to first entry in the options menu list */
+static
+struct option_menu *FirstMenu = NULL;
+static
+struct option_menu *CurrentMenu = NULL;	/* menu currently looked at */
+int     MenuPage = 1;		/* current menu page */
+int     MaxOptions = 0;		/* maximum number of options in all menu
+				   pages */
+struct int_range MenuPages =
+{1, 1, 1};
+
+/* range of updates for keep-info-window-up option */
+struct int_range keepInfo_range =
+{0, 100, 1};
+
+/* updates: use of the int range thing... */
+struct int_range updates_range =
+{1, 10, 1};
+
+struct int_range redraw_delay_range =
+{0, 10, 1};
+
+/* range of menus. Will be updated when menu list is assembled */
+struct int_range Menus_Range =
+{1, 1, 1};
+
+#ifdef CONTINUOUS_MOUSE
+struct int_range clickDelay_range =
+{0, 20, 1};
+#endif				/* CONTINUOUS_MOUSE */
+
+#ifdef BEEPLITE
+struct int_range beeplite_planet_range =
+{0, 50, 1};
+struct int_range beeplite_player_range =
+{0, 50, 1};
+#endif
+
+struct int_range zoom_override_range =
+{0, 99, 1};
+
+#ifdef LOCAL_SHIPSTATS
+struct int_range statHeight_range =
+{4,100, 4};
+#endif
+
+/* range for tacPlanetInfo */
+struct int_range tacPlanetInfo_range = {0, 31, 1};
+
+/* menus */
+
+struct option Features_Menu[] =
+{
+    {"Defaults Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {0, &mapmode, 0, 0, 0, mapupdates, NULL},
+    {0, &showgalactic, 0, 0, 0, galacticmes, NULL},
+    {0, &showlocal, 0, 0, 0, localmes, NULL},
+#ifdef SHOW_IND
+    {"show IND planets", &showIND, 0, 0, 0, NULL, NULL},
+#endif
+    {"send MOTD bitmaps", &sendmotdbitmaps, 0, 0, 0, NULL, NULL},
+    {"reload ship bitmaps", &reloadShipBitmaps, 0, 0, 0, NULL, NULL},
+    {"stay peaceful when reborn", &keeppeace, 0, 0, 0, NULL, NULL},
+    {0, &remapAllShips, 0, 0, 0, keymapmes, NULL},
+    {"new keymap entries: %s_", 0, 0, newkeys, 13, NULL, NULL},
+    {"new ckeymap entries: %s_", 0, 0, newckeys, 13, NULL, NULL},
+    {"new buttonmap entries: %s_", 0, 0, newbuttons, 13, NULL, NULL},
+    {"new cbuttonmap entries: %s_", 0, 0, newcbuttons, 13, NULL, NULL},
+    {"report kill messages", &reportKills, 0, 0, 0, NULL, NULL},
+#if 0
+    /* need to figure out how to dispatch options */
+    {"recv variable packets", &recv_short, 0, 0, 0, NULL},
+    {"recv kill messages", &recv_kmesg, 0, 0, 0, NULL},
+#endif
+    {"keep info %d upds (0=forever)", &keepInfo, 0, 0, 0, 0, &keepInfo_range},
+    {"%d updates per second", &updateSpeed, 0, 0, 0, 0, &updates_range},
+    {"%d/10 sec screen refresh delay", &redrawDelay, 0, 0, 0, 0, &redraw_delay_range}, 
+    {"collect ping stats", &ping, 0, 0, 0, NULL, NULL},
+    {"avoid message kludge", &niftyNewMessages, 0, 0, 0, NULL, NULL},
+#ifdef CONTINUOUS_MOUSE
+    {"use continuous mouse", &continuousMouse, 0, 0, 0, NULL, NULL},
+    {"%d updates repeat delay", &clickDelay, 0, 0, 0, 0, &clickDelay_range},
+#endif				/* CONTINUOUS_MOUSE */
+#ifdef UNIX_SOUND
+    {"play sound effects", &playSounds, 0, 0, 0, NULL, NULL},
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+struct option Window_Menu[] =
+{
+    {"Window Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"show \"all\" message window", 0, &messWin[WALL].window, 0, 0, NULL, NULL},
+    {"show \"team\" message window", 0, &messWin[WTEAM].window, 0, 0, NULL, NULL},
+    {"show \"your\" message window", 0, &messWin[WINDIV].window, 0, 0, NULL, NULL},
+    {"show \"kill\" message window", 0, &messWin[WKILL].window, 0, 0, NULL, NULL},
+    {"show \"phaser\" message window", 0, &messWin[WPHASER].window, 0, 0, NULL, NULL},
+    {"show \"joined\" message window", 0, &messWin[WREVIEW].window, 0, 0, NULL, NULL},
+    {"show ship statistics window", 0, &statwin, 0, 0, NULL, NULL},
+    {"show network statistics window", 0, &pStats, 0, 0, NULL, NULL},
+    {"show help window", 0, &helpWin, 0, 0, NULL, NULL},
+#ifdef XTREKRC_HELP
+    {"show xtrekrc defaults window", 0, &defWin, 0, 0, NULL, NULL},
+#endif
+#ifdef TOOLS
+    {"show shell tools window", 0, &toolsWin, 0, 0, NULL, NULL},
+#endif
+    {0, &showPhaser, 0, 0, 0, phaseroptions, NULL},
+    {"", &showLock, 0, 0, 0, lockoptions, NULL},
+    {"show lock line", &lockLine, 0, 0, 0, NULL, NULL},
+    {"sort planets by team", &mapSort, 0, 0, 0, NULL, NULL},
+#ifdef NOWARP
+    {"enable message warp", &warp, 0, 0, 0, NULL, NULL},
+#endif
+    {"use info icon", &infoIcon, 0, 0, 0, NULL, NULL},
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+struct option Display_Menu[] =
+{
+    {"Features Display Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+#ifdef ROTATERACE
+    {0, &rotate, 0, 0, 0, rotatemess, NULL},
+#endif
+    {"draw background stars", &blk_showStars, 0, 0, 0, NULL},
+    {"show warp/star streaks", &warpStreaks, 0, 0, 0, NULL, NULL},
+    {"show tractor/pressor", &showTractorPressor, 0, 0, 0, NULL, NULL},
+    {"show all tractors/pressors", &showAllTractorPressor, 0, 0, 0, NULL, NULL},
+    {"show shields", &showShields, 0, 0, 0, NULL, NULL},
+    {"show shield damage", &show_shield_dam, 0, 0, 0, NULL, NULL},
+#ifdef VARY_HULL
+    {"show hull damage indicators", &vary_hull, 0, 0, 0, NULL, NULL},
+#endif				/* VARY_HULL */
+
+    {"show tactical planet names", &namemode, 0, 0, 0, NULL, NULL},
+
+    {"zoom galactic map", &blk_zoom, 0, 0, 0, NULL, NULL},
+    {0,&autoZoom, 0, 0, 0, autoZoomOpts, NULL},
+    {0,&autoUnZoom, 0, 0, 0, autoUnZoomOpts, NULL},
+    {"Manual zoom overrides auto-zoom %d updates",&autoZoomOverride, 0, 0, 0, NULL, 
+	 &zoom_override_range},
+    {"draw galactic map grid", &drawgrid, 0, 0, 0, NULL},
+    {"show sector numbers", &sectorNums, 0, 0, 0, NULL, NULL},
+    {"show view box", &viewBox, 0, 0, 0, NULL, NULL},
+    {0, &autoSetWar, 0, 0, 0, autoSetWarOpts, NULL},
+    {"show planet info on tactical: %d", &tacPlanetInfo, 0, 0, 0, 0, &tacPlanetInfo_range},
+#ifdef BEEPLITE
+    {"use RCD highlighting", &UseLite, 0, 0, 0, NULL, NULL},
+    {"highlight/use default RCDs", &DefLite, 0, 0, 0, NULL, NULL},
+    {"No. of updates to highlight player: %d", &beep_lite_cycle_time_player,
+    0, 0, 0, NULL, &beeplite_player_range},
+    {"No. of updates to highlight planet: %d", &beep_lite_cycle_time_planet,
+    0, 0, 0, NULL, &beeplite_planet_range},
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+struct option Playerdash_Menu[] =
+{
+    {"Playerlist/Dashboard Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"sort playerlist", &sortPlayers, 0, 0, 0, NULL, NULL},
+    {"show dead players in playerlist", &showDead, 0, 0, 0, NULL, NULL},
+    {"show players as they log in", &showPreLogins, 0, 0, 0, NULL, NULL},
+    {"hide 0.00 kills in playerlist", &hideNoKills, 0, 0, 0, NULL, NULL},
+    {"sort outfitting to bottom", &sortOutfitting, 0, 0, 0, NULL, NULL},
+    {0, &Dashboard, 0, 0, 0, dashboardoptions, NULL},
+#ifdef TIMER
+    {0, &timerType, 0, 0, 0, timermes, NULL},
+#endif				/* TIMER */
+#ifdef LOCAL_SHIPSTATS
+    {"show ship stats on local window",&localShipStats, 0, 0, 0, NULL, NULL},
+    {"Local ship stats height: %d",&statHeight, 0, 0, 0, NULL, &statHeight_range},
+#endif
+#ifdef PACKET_LIGHTS
+    {"show packet lights", &packetLights, 0, 0, 0, NULL, NULL},
+#endif
+    {"keep phaser statistics", &phaserStats,0,0,0,NULL, NULL},
+    {"clear phaser statistics", &clearPhaserStats, 0, 0, 0, NULL, NULL},
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+#ifdef HOCKEY
+struct option Hockey_Menu[] =
+{
+    {"Hockey Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"show tactical hockey lines", &tacticalHockeyLines, 0, 0, 0, NULL, NULL},
+    {"show galactic hockey lines", &galacticHockeyLines, 0, 0, 0, NULL, NULL},
+    {"show planets on the galactic", &cleanHockeyGalactic, 0, 0, 0, NULL, NULL},
+    {"color hockey lines by team", &teamColorHockeyLines, 0, 0, 0, NULL, NULL},
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+#endif /*HOCKEY*/
+
+#if 0
+struct option Network_Menu[] =
+{
+    {"Network menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+#endif				/* 0 */
+
+#if 0
+{
+    "show shields", &showShields, 0, 0, 0, NULL, NULL
+},
+{
+    "show UDP control window", 0, &udpWin, 0, 0, NULL, NULL
+},
+{
+    "show short packets window", 0, &spWin, 0, 0, NULL, NULL
+},
+struct option SillyFeatures_Menu[] =
+{
+    {"Silly Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"alert on extra border(s)", &extraBorder, 0, 0, 0, NULL, NULL},
+#ifdef BORGTEST
+    {"borg torp test", &bd, 0, 0, 0, NULL, NULL},	/* BORG TEST */
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+#endif				/* 0 */
+
+#ifdef AMIGA
+
+static char *autopointmess[] = {
+    "AutoPoint: none",
+    "AutoPoint: Redirect input",
+    "AutoPoint: Activate window on input",
+    "AutoPoint: Full (inefficient)", ""
+};
+
+static char *dooshSoundMess[] = {
+    "Play doosh sound when YOU kill a carrier",
+    "Play doosh sound when ANY carrier dies",
+    ""
+};
+
+struct int_range soundVolRange = {0, 64, 4};
+struct int_range speechVolRange = {0, 64, 4};
+
+extern int speechVol;
+extern int S_AddPeriod;
+extern int monoBitmaps;
+
+struct option Amiga_Menu[] = {
+    {"Amiga Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {0, &autoPoint, 0, 0, 0, autopointmess, NULL},
+    {"do keyboard window depth", &W_KeyDepth, 0, 0, 0, NULL, NULL},
+    {"use AnimPointers", &animPointers, 0, 0, 0, NULL, NULL},
+    {"use one color bitmaps", &monoBitmaps, 0, 0, 0, NULL, NULL},
+    {"use Workbench screen", &useWorkbench, 0, 0, 0, NULL, NULL},
+    {"speak messages to \"all\"", &S_SpeakAll, 0, 0, 0, NULL, NULL},
+    {"speak messages to you", &S_SpeakYour, 0, 0, 0, NULL, NULL},
+    {"speak messages to team", &S_SpeakTeam, 0, 0, 0, NULL, NULL},
+    {"speak \"kill\" messages", &S_SpeakKill, 0, 0, 0, NULL, NULL},
+    {"speak messages from God", &S_SpeakGod, 0, 0, 0, NULL, NULL},
+    {"speak messages from YOU", &S_SpeakSelf, 0, 0, 0, NULL, NULL}, 
+    {"speak login/out messages", &S_SpeakLogins, 0, 0, 0, NULL, NULL},
+    {"ignore repeated messages", &S_IgnoreMultiple, 0, 0, 0, 0, 0},
+    {"add a period to the end of messages", &S_AddPeriod, 0, 0, 0, 0, 0},
+    {"Speech volume: %d", &speechVol, 0, 0, 0, NULL, &speechVolRange},
+#ifdef SOUND
+    {"play digitized sounds", &soundOn, 0, 0, 0, NULL, NULL},
+    {"Sound volume: %d", &soundVol, 0, 0, 0, NULL, &soundVolRange},
+    {"show sounds window", 0, &soundWin, 0, 0, NULL, NULL},
+    {0, &alwaysSoundDoosh, 0, 0, 0, dooshSoundMess, 0},
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+#endif				/* AMIGA */
+
+#define NUMOPTIONS(menu) ((sizeof((menu))/sizeof((menu)[0]))-1)
+
+
+/* option menu sizes and such */
+#define OPTIONBORDER	2
+#define OPTIONLEN	40
+
+static void RefreshOptions P((void));
+static void SetMenuPage P((int pagenum));
+static int InitOptionMenus P((void));
+static void AddOptMenu P((struct option NewMenu[], int updated));
+static int NumOptions P((struct option OpMenu[]));
+/*static void UpdateOptions P((void));*/
+void optionrefresh P((register struct option * op));
+
+
+/* Set up the option menus and window. */
+void
+optionwindow()
+{
+    /* Init not done flag */
+    notdone = 1;
+
+    old_ping = ping;
+    old_rotate = rotate;
+    old_rotate_deg = rotate_deg;
+
+    *newkeys = '\0';
+    *newckeys = '\0';
+    *newbuttons = '\0';
+    *newcbuttons = '\0';
+    if (FirstMenu == NULL) {
+	if (!paradise) {	/* remove the extra planet settings */
+	    localmes[3] = "";
+	    galacticmes[3] = "";
+	}
+	MaxOptions = InitOptionMenus();
+	if (MaxOptions < 0) {
+	    fprintf(stderr, "InitOptionMenus() error %d!\n", MaxOptions);
+	    notdone = 0;
+	    return;
+	}
+    }
+    /* Create window big enough to hold option windows */
+    if (optionWin == NULL) {
+
+	optionWin = W_MakeMenu("option", WINSIDE + 10, -BORDER + 10, OPTIONLEN,
+			       MaxOptions, baseWin, OPTIONBORDER);
+	CurrentMenu = FirstMenu;
+
+	RefreshOptions();
+    }
+    W_ResizeMenu(optionWin, OPTIONLEN, CurrentMenu->numopt);
+    /* Map window */
+    W_MapWindow(optionWin);
+}
+
+/* refresh all current options */
+static void
+RefreshOptions()
+{
+    int     i;
+    struct option_menu *option;
+
+    if (notdone == 0 || (option = CurrentMenu) == NULL)
+	return;
+
+    for (i = 0; i < option->numopt; i++) {
+	optionrefresh(&(option->menu[i]));
+    }
+#ifdef nodef			/* if we resize, we don't need this */
+    if (option->numopt < MaxOptions)
+	for (i = option->numopt; i < MaxOptions; i++) {
+	    OptionClear(i);
+	}
+#endif
+}
+
+#ifdef nodef
+/* blank out option line 'i' */
+static void
+OptionClear(i)
+{
+    char   *blanktext = "                                               ";
+    if (optionWin && notdone)
+	W_WriteText(optionWin, 0, i, textColor, blanktext, OPTIONLEN, 0);
+}
+#endif
+
+/* Redraw the specified option entry */
+void
+optionredrawtarget(win)
+    W_Window win;
+{
+    register struct option *op;
+
+#ifdef nodef
+    if (notdone == 0)
+	return;
+#endif
+
+    for (op = CurrentMenu->menu; op->op_text; op++) {
+	if (op->op_targetwin && win == *op->op_targetwin) {
+	    optionrefresh(op);
+	    break;
+	}
+    }
+}
+
+/* Redraw the specified option option */
+void
+optionredrawoption(ip)
+    int    *ip;
+{
+    register struct option *op;
+
+#ifdef nodef
+    if (notdone == 0)
+	return;
+#endif
+
+    for (op = CurrentMenu->menu; op->op_num >= 0; op++) {
+	if (ip == op->op_option) {
+	    optionrefresh(op);
+	    break;
+	}
+    }
+}
+
+/* Refresh the option window given by the option struct */
+void
+optionrefresh(op)
+    register struct option *op;
+{
+    register int on;
+    char    buf[BUFSIZ];
+
+    if (op == NULL || notdone == 0)
+	return;
+
+    if (op->op_string) {
+	(void) sprintf(buf, op->op_text, op->op_string);
+    } else if (op->op_array) {	/* Array of strings */
+	strcpy(buf, op->op_array[*op->op_option]);
+    } else if (op->op_range) {
+	(void) sprintf(buf, op->op_text, *(op->op_option));
+    } else {
+	/* Either a boolean or a window */
+	if (op->op_option)
+	    on = *op->op_option;/* use int for status */
+	else if (op->op_targetwin)
+	    on = W_IsMapped(*op->op_targetwin);	/* use window for status */
+	else
+	    on = 1;		/* shouldn't happen */
+
+	if (!on)
+	    strcpy(buf, "Don't ");
+	else
+	    buf[0] = '\0';
+	strcat(buf, op->op_text);
+    }
+
+    if (islower(buf[0]))
+	buf[0] = toupper(buf[0]);
+
+    if (op->op_num == 0) {	/* title */
+	W_WriteText(optionWin, 0, op->op_num, W_Yellow, buf, strlen(buf), 0);
+    } else if (op->op_num == 1) {	/* "click" entry */
+	W_WriteText(optionWin, 0, op->op_num, W_Green, buf, strlen(buf), 0);
+    } else
+	W_WriteText(optionWin, 0, op->op_num, textColor, buf, strlen(buf), 0);
+}
+
+/* deal with events sent to the option window */
+int
+optionaction(data)
+    W_Event *data;
+{
+    register struct option *op;
+    int     i;
+    register char *cp;
+
+    if (data->y >= CurrentMenu->numopt) {
+	W_Beep();
+	return (0);
+    }
+    if (notdone == 0)
+	return (0);
+
+    op = &(CurrentMenu->menu[data->y]);
+
+    /* Update string; don't claim keystrokes for non-string options */
+    /* deal with options with string input first */
+    if (op->op_string == 0) {
+	if (data->type == W_EV_KEY)
+	    return (0);
+    } else {
+	if (data->type == W_EV_BUTTON)
+	    return (0);
+	switch (data->key) {
+
+	case '\b':		/* delete character */
+	case '\177':
+	    cp = op->op_string;
+	    i = strlen(cp);
+	    if (i > 0) {
+		cp += i - 1;
+		*cp = '\0';
+	    }
+	    break;
+
+	case '\027':		/* word erase */
+	    cp = op->op_string;
+	    i = strlen(cp);
+	    /* back up over blanks */
+	    while (--i >= 0 && isspace(cp[i]));
+	    i++;
+	    /* back up over non-blanks */
+	    while (--i >= 0 && !isspace(cp[i]));
+	    i++;
+	    cp[i] = '\0';
+	    break;
+
+	case '\025':		/* kill line */
+	case '\030':
+	    op->op_string[0] = '\0';
+	    break;
+
+	default:		/* add character to the list */
+	    if (data->key < 32 || data->key > 127)
+		break;
+	    cp = op->op_string;
+	    i = strlen(cp);
+	    if (i < (op->op_size - 1) && !iscntrl(data->key)) {
+		cp += i;
+		cp[1] = '\0';
+		cp[0] = data->key;
+	    } else
+		W_Beep();
+	    break;
+	}
+    }
+
+    /* Toggle int, if it exists */
+    if (op->op_array) {
+	if (data->key == W_LBUTTON) {
+	    (*op->op_option)++;
+	    if (*(op->op_array)[*op->op_option] == '\0') {
+		*op->op_option = 0;
+	    }
+	} else if (data->key == W_MBUTTON) {
+	    /* set option number to zero on the middle key to ease shutoff */
+	    *op->op_option = 0;
+	} else if (data->key == W_RBUTTON) {
+	    /* if right button, decrease option  */
+	    (*op->op_option)--;
+	    /* if decreased too far, set to top option */
+	    if (*(op->op_option) < 0) {
+		*op->op_option = 0;
+		while (*(op->op_array)[*op->op_option] != '\0') {
+		    (*op->op_option)++;
+		}
+		(*op->op_option)--;
+	    }
+	}
+	if(op->op_option == &showgalactic)
+	    redrawall=1;
+    } else if (op->op_range) {
+	 if (data->key == W_RBUTTON) {
+	      if (op->op_range->increment == -1) /* bitwise shifts by 1 */
+		   if (*op->op_option == 0)
+			(*op->op_option) = op->op_range->max_value;
+		   else
+			(*op->op_option) = (*op->op_option) >> 1;
+	      else
+		   (*op->op_option) -= op->op_range->increment;
+	} else if (data->key == W_MBUTTON) {
+	    (*op->op_option) = op->op_range->min_value;
+	} else if (data->key == W_LBUTTON) {
+	     if (op->op_range->increment == -1)
+		  if (*op->op_option == 0)
+		       (*op->op_option) = 1;
+		  else
+		       (*op->op_option) =  (*op->op_option) << 1;
+	     else
+		  (*op->op_option) += op->op_range->increment;
+	}
+	/* wrap value around within option range */
+	if (*(op->op_option) > op->op_range->max_value)
+	    *(op->op_option) = op->op_range->min_value;
+	if (*(op->op_option) < op->op_range->min_value)
+	    *(op->op_option) = op->op_range->max_value;
+    } else if (op->op_option) {
+	*op->op_option = !*op->op_option;
+	if(op->op_option == &blk_zoom) {
+	    if(!paradise) {
+		blk_zoom=0;
+	    } else {
+		redrawall=1;
+	    }
+	} else if((op->op_option == &blk_showStars) && !paradise)
+	    blk_showStars = 0;
+	else if((op->op_option == &drawgrid) ||
+		(op->op_option == &sectorNums))
+	    redrawall=1;
+	else if(op->op_option == &clearPhaserStats) {
+	    phasFired=phasHits=totalDmg=0;
+	    clearPhaserStats=1;
+	    warning("Phaser statistics reset!");
+	} else if(op->op_option == &reloadShipBitmaps) {
+	    free_shipshapes();
+	    slurp_ship_bitmaps();
+	    reloadShipBitmaps = 1;
+	    warning("Read ship bitmaps");
+	}
+#ifdef AMIGA
+	else if(op->op_option == &useWorkbench) {
+	    switchScreen();
+	}
+#endif
+    }
+    /* Map/unmap window, if it exists */
+    if (op->op_targetwin) {
+	if (W_IsMapped(*op->op_targetwin)) {
+	    if (*op->op_targetwin == udpWin)
+		udpdone();
+	    else if (*op->op_targetwin == spWin)
+		spdone();
+	    else
+		W_UnmapWindow(*op->op_targetwin);
+	} else {
+	    if (*op->op_targetwin == udpWin)
+		udpwindow();
+	    else if (*op->op_targetwin == spWin)
+		spwindow();
+#ifdef SOUND
+	    else if (*op->op_targetwin == soundWin)
+		S_SoundWindow();
+#endif
+	    else
+		W_MapWindow(*op->op_targetwin);
+	    if (*op->op_targetwin == pStats)
+		redrawPStats();
+#ifdef XTREKRC_HELP
+	    if (*op->op_targetwin == defWin)
+		showdef();
+#endif
+	}
+    }
+    /* deal with possible menu change */
+    if (MenuPage != CurrentMenu->page_num) {
+	SetMenuPage(MenuPage);
+	RefreshOptions();
+    }
+    if (!notdone)		/* if done, that is */
+	optiondone();
+    else
+	optionrefresh(op);
+
+
+    return (1);
+}
+
+/*
+ * find the menu in the menus linked list that matches the one in the *
+ * argument
+ */
+static void
+SetMenuPage(pagenum)
+    int     pagenum;
+{
+    int     i = 1;
+    if (FirstMenu != NULL)
+	for (CurrentMenu = FirstMenu; CurrentMenu->Next != NULL &&
+	     CurrentMenu->page_num != pagenum; i++, CurrentMenu = CurrentMenu->Next);
+    W_ResizeMenu(optionWin, OPTIONLEN, CurrentMenu->numopt);
+}
+
+void
+optiondone()
+{
+    int shpn;
+    struct ship *shp;
+
+    /* Unmap window */
+    W_UnmapWindow(optionWin);
+
+    if(remapAllShips) {
+	for(shpn=0;shpn<nshiptypes;shpn++) {
+	    shp=getship(shpn);
+	    keymapAdd(newkeys, shp->s_keymap);
+	    ckeymapAdd(newckeys, shp->s_keymap);
+	    buttonmapAdd(newbuttons, shp->s_buttonmap);
+	    cbuttonmapAdd(newcbuttons, shp->s_buttonmap);
+	}
+    } else { /* only affect current ship */
+	/* update keymap and buttonmap [Bdyess] */
+	keymapAdd(newkeys, myship->s_keymap);
+	ckeymapAdd(newckeys, myship->s_keymap);
+	buttonmapAdd(newbuttons, myship->s_buttonmap);
+	cbuttonmapAdd(newcbuttons, myship->s_buttonmap);
+    }
+
+    /* optionrefresh(&(option[KEYMAP])); Not sure why this is really needed */
+
+    sendOptionsPacket();	/* update server as to the client's options */
+
+    if (updateSpeed != lastUpdateSpeed) {
+	sendUpdatePacket(1000000 / updateSpeed);
+	lastUpdateSpeed = updateSpeed;
+    }
+    if (oldzoom != blk_zoom) {
+	redrawall = 1;
+	oldzoom = blk_zoom;
+    }
+    if (ping != old_ping) {
+	old_ping = ping;
+	if (ping)
+	    startPing();
+	else
+	    stopPing();
+    }
+#ifdef BEEPLITE
+    if (DefLite)
+	litedefaults();
+#endif
+
+#ifdef ROTATERACE
+    if (rotate != old_rotate) {
+
+	rotate_all();
+#if 0
+	register i;
+	register struct planet *l;
+	int     nplan = (paradise) ? nplanets : 40;
+
+	redrawall = 1;
+	reinitPlanets = 1;
+
+	for (i = 0, l = planets; i < nplan; i++, l++) {
+	    if (rotate) {
+		rotate_deg = -old_rotate_deg + rotate * 64;
+		rotate_coord(&l->pl_x, &l->pl_y, rotate_deg,
+			     blk_gwidth / 2, blk_gwidth / 2);
+		rotate_deg = rotate * 64;
+	    } else {
+		rotate_deg = -old_rotate_deg;
+		rotate_coord(&l->pl_x, &l->pl_y, rotate_deg,
+			     blk_gwidth / 2, blk_gwidth / 2);
+		rotate_deg = 0;
+	    }
+	}
+#endif
+	old_rotate = rotate;
+	old_rotate_deg = rotate_deg;
+
+    }
+#endif
+}
+
+/* set up menus linked list */
+static int
+InitOptionMenus()
+{
+    int     i = 1;
+    int     maxopts = 0;
+
+    IFDEBUG(printf("Adding OptionMenus\n");
+    )
+    /* AddOptMenu( &OptionsMenu, 0); */
+	AddOptMenu(Features_Menu, 0);
+    AddOptMenu(Window_Menu, 0);
+    AddOptMenu(Display_Menu, 0);
+    AddOptMenu(Playerdash_Menu, 0);
+#ifdef HOCKEY
+    AddOptMenu(Hockey_Menu, 0);
+#endif /*HOCKEY*/
+#ifdef AMIGA
+    AddOptMenu(Amiga_Menu, 0);
+#endif
+    /* AddOptMenu(SillyFeatures_Menu, 0); */
+    /* AddOptMenu(Network_Menu, 0); */
+
+    for (i = 1, CurrentMenu = FirstMenu; CurrentMenu != NULL;
+	 i++, CurrentMenu = CurrentMenu->Next) {
+	CurrentMenu->page_num = i;	/* repage the menus.. */
+	if (CurrentMenu->numopt > maxopts)
+	    maxopts = CurrentMenu->numopt;
+    }
+    CurrentMenu = FirstMenu;
+    Menus_Range.max_value = i - 1;
+    IFDEBUG(printf("OptionMenus Added! Maxopt = %d \n", i);
+    )
+	return maxopts;
+}
+
+static void
+AddOptMenu(NewMenu, updated)
+    struct option NewMenu[];
+    int     updated;
+{
+    struct option_menu *menuptr;
+    struct option_menu *newmenu;
+    int     i = 0;
+
+    IFDEBUG(printf("AddOptMenu\n");
+    )
+	menuptr = FirstMenu;
+
+    newmenu = (struct option_menu *) malloc(sizeof(struct option_menu));
+    if (newmenu == NULL) {
+	perror("Malloc Error adding a menu");
+	return;
+    }
+    /* add to list */
+    if (FirstMenu == NULL) {
+	FirstMenu = newmenu;
+    } else {
+	for (i = 0, menuptr = FirstMenu; menuptr->Next != NULL; menuptr = menuptr->Next)
+	    i++;
+	menuptr->Next = newmenu;
+    }
+    newmenu->page_num = i;
+    newmenu->Next = NULL;
+    newmenu->numopt = NumOptions(NewMenu);
+    newmenu->menu = NewMenu;
+    newmenu->updated = updated;
+    IFDEBUG(printf("Menu Added! \n", i);
+    )
+}
+
+static int
+NumOptions(OpMenu)
+    struct option OpMenu[];
+{
+    int     i = 0;
+    struct option *ptr;
+
+    ptr = &OpMenu[0];
+    for (i = 0; ptr->op_num != -1 && ptr->op_option != &notdone; i++) {
+	IFDEBUG(printf("Option #%d..\n", i);
+	)
+	    IFDEBUG(if (ptr->op_text != NULL) printf("OP_Text:%s\n", ptr->op_text);
+	)
+	    ptr = &OpMenu[i];
+	ptr->op_num = i;
+    }
+
+    IFDEBUG(printf("NumOptions in this menu: %d\n", i);
+    )
+	return i;
+}
+
+/*
+ * a function that could be called regularly, to deal with menus that * might
+ * be updated by external events. I.e. the udp menu!
+ */
+#if 0
+static void
+UpdateOptions()
+{
+    if (notdone == 0)
+	return;			/* don't update if menu isn't in use */
+    if (CurrentMenu->updated)
+	RefreshOptions();
+}
+#endif				/* 0 */