Mercurial > ~darius > hgwebdir.cgi > paradise_client
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", ¬done, 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", ¬done, 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", §orNums, 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", ¬done, 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", ¬done, 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", ¬done, 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", ¬done, 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", ¬done, 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", ¬done, 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 == §orNums)) + 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 != ¬done; 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 */