diff xrogue/options.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children ce0cf824c192
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xrogue/options.c	Tue Apr 21 08:55:20 2015 -0400
@@ -0,0 +1,501 @@
+/*
+    options.c - This file has all the code for the option command
+    
+    XRogue: Expeditions into the Dungeons of Doom
+    Copyright (C) 1991 Robert Pietkivitch
+    All rights reserved.
+    
+    Based on "Advanced Rogue"
+    Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+    All rights reserved.
+
+    Based on "Rogue: Exploring the Dungeons of Doom"
+    Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+    All rights reserved.
+    
+    See the file LICENSE.TXT for full copyright and licensing information.
+*/  
+    
+ /*
+ * I would rather this command were not necessary, but
+ * it is the only way to keep the wolves off of my back.
+ */
+
+#include <curses.h>
+#include <ctype.h>
+#include "rogue.h"
+
+#define NUM_OPTS        (sizeof optlist / sizeof (OPTION))
+
+/*
+ * description of an option and what to do with it
+ */
+struct optstruct {
+    char        *o_name;        /* option name */
+    char        *o_prompt;      /* prompt for interactive entry */
+    int         *o_opt;         /* pointer to thing to set */
+    int         (*o_putfunc)(); /* function to print value */
+    int         (*o_getfunc)(); /* function to get value interactively */
+};
+
+typedef struct optstruct        OPTION;
+
+int     put_bool(), 
+        get_bool(),
+        put_str(),
+        get_str(),
+        put_abil(),
+        get_abil(),
+        get_quest(),
+        put_quest(),
+    get_default();
+
+OPTION  optlist[] = {
+    {"terse",   "Terse output: ",
+                (int *) &terse,         put_bool,       get_bool        },
+    {"flush",   "Flush typeahead during battle: ",
+                (int *) &fight_flush,   put_bool,       get_bool        },
+    {"jump",    "Show position only at end of run: ",
+                (int *) &jump,          put_bool,       get_bool        },
+    {"step",    "Do inventories one line at a time: ",
+                (int *) &slow_invent,   put_bool,       get_bool        },
+    {"askme",   "Ask me about unidentified things: ",
+                (int *) &askme,         put_bool,       get_bool        },
+    {"pickup",  "Pick things up automatically: ",
+                (int *) &auto_pickup,   put_bool,       get_bool        },
+    {"overlay", "Overlay menu: ",
+                (int *) &menu_overlay,  put_bool,       get_bool        },
+    {"name",    "Name: ",
+                (int *) whoami,         put_str,        get_str         },
+    {"file",    "Save file: ",
+                (int *) file_name,      put_str,        get_str         },
+    {"score",   "Score file: ",
+                (int *) score_file,     put_str,        get_str         },
+    {"class",   "Character type: ",
+                (int *) &char_type,     put_abil,       get_abil        },
+    {"quest",   "Quest item: ",
+                (int *) &quest_item,    put_quest,      get_quest       },
+    {"default", "Default Attributes: ",
+                (int *) &def_attr,      put_bool,    get_default     }
+};
+
+/*
+ * The default attribute field is read-only
+ */
+
+get_default(bp, win)
+bool *bp;
+WINDOW *win;
+{
+    register int oy, ox;
+
+    getyx(win, oy, ox);
+    put_bool(bp, win);
+    get_ro(win, oy, ox);
+}
+
+/*
+ * The ability (class) field is read-only
+ */
+
+get_abil(abil, win)
+int *abil;
+WINDOW *win;
+{
+    register int oy, ox;
+
+    getyx(win, oy, ox);
+    put_abil(abil, win);
+    get_ro(win, oy, ox);
+}
+
+/*
+ * The quest field is read-only
+ */
+
+get_quest(quest, win)
+int *quest;
+WINDOW *win;
+{
+    register int oy, ox;
+
+    getyx(win, oy, ox);
+    waddstr(win, rel_magic[*quest].mi_name);
+    get_ro(win, oy, ox);
+}
+
+/*
+ * get_ro:
+ *      "Get" a read-only value.
+ */
+
+get_ro(win, oy, ox)
+WINDOW *win;
+register int oy, ox;
+{
+    register int ny, nx;
+    register bool op_bad;
+    
+    op_bad = TRUE;
+    getyx(win, ny, nx);
+    while(op_bad)       
+    {
+        wmove(win, oy, ox);
+        draw(win);
+        switch (wgetch(win))
+        {
+            case '\n':
+            case '\r':
+                op_bad = FALSE;
+                break;
+            case '\033':
+            case '\007':
+                return QUIT;
+            case '-':
+                return MINUS;
+            default:
+                mvwaddstr(win, ny, nx + 5, "(no change allowed)");
+        }
+    }
+    wmove(win, ny, nx + 5);
+    wclrtoeol(win);
+    wmove(win, ny, nx);
+    waddch(win, '\n');
+    return NORM;
+}
+
+/*
+ * allow changing a boolean option and print it out
+ */
+
+get_bool(bp, win)
+bool *bp;
+WINDOW *win;
+{
+    register int oy, ox;
+    register bool op_bad;
+
+    op_bad = TRUE;
+    getyx(win, oy, ox);
+    waddstr(win, *bp ? "True" : "False");
+    while(op_bad)       
+    {
+        wmove(win, oy, ox);
+        draw(win);
+        switch (wgetch(win))
+        {
+            case 't':
+            case 'T':
+                *bp = TRUE;
+                op_bad = FALSE;
+                break;
+            case 'f':
+            case 'F':
+                *bp = FALSE;
+                op_bad = FALSE;
+                break;
+            case '\n':
+            case '\r':
+                op_bad = FALSE;
+                break;
+            case '\033':
+            case '\007':
+                return QUIT;
+            case '-':
+                return MINUS;
+            default:
+                mvwaddstr(win, oy, ox + 10, "(T or F)");
+        }
+    }
+    wmove(win, oy, ox);
+    wclrtoeol(win);
+    waddstr(win, *bp ? "True" : "False");
+    waddch(win, '\n');
+    return NORM;
+}
+
+/*
+ * set a string option
+ */
+
+get_str(opt, win)
+register char *opt;
+WINDOW *win;
+{
+    register char *sp;
+    register int c, oy, ox;
+    char buf[LINELEN];
+
+    draw(win);
+    getyx(win, oy, ox);
+    /*
+     * loop reading in the string, and put it in a temporary buffer
+     */
+    for (sp = buf;
+        (c = wgetch(win)) != '\n'       && 
+        c != '\r'                       && 
+        c != '\033'                     && 
+        c != '\007'                     &&
+        sp < &buf[LINELEN-1];
+        wclrtoeol(win), draw(win))
+    {
+        if (c == -1)
+            continue;
+        else if (c == erasechar()) /* process erase character */
+        {
+            if (sp > buf)
+            {
+                register int i;
+
+                sp--;
+                for (i = strlen(unctrl(*sp)); i; i--)
+                    waddch(win, '\b');
+            }
+            continue;
+        }
+        else if (c == killchar()) /* process kill character */
+        {
+            sp = buf;
+            wmove(win, oy, ox);
+            continue;
+        }
+        else if (sp == buf)
+            if (c == '-' && win == hw)  /* To move back a line in hw */
+                break;
+            else if (c == '~')
+            {
+                strcpy(buf, home);
+                waddstr(win, home);
+                sp += strlen(home);
+                continue;
+            }
+        *sp++ = c;
+        waddstr(win, unctrl(c));
+    }
+    *sp = '\0';
+    if (sp > buf)       /* only change option if something has been typed */
+        strucpy(opt, buf, strlen(buf));
+    wmove(win, oy, ox);
+    waddstr(win, opt);
+    waddch(win, '\n');
+    draw(win);
+    if (win == msgw)
+        mpos += sp - buf;
+    if (c == '-')
+        return MINUS;
+    else if (c == '\033' || c == '\007')
+        return QUIT;
+    else
+        return NORM;
+}
+
+/*
+ * print and then set options from the terminal
+ */
+
+option()
+{
+    register OPTION     *op;
+    register int        retval;
+
+    wclear(hw);
+    touchwin(hw);
+    /*
+     * Display current values of options
+     */
+    for (op = optlist; op < &optlist[NUM_OPTS]; op++)
+    {
+        waddstr(hw, op->o_prompt);
+        (*op->o_putfunc)(op->o_opt, hw);
+        waddch(hw, '\n');
+    }
+    /*
+     * Set values
+     */
+    wmove(hw, 0, 0);
+    for (op = optlist; op < &optlist[NUM_OPTS]; op++)
+    {
+        waddstr(hw, op->o_prompt);
+
+		retval = (*op->o_getfunc)(op->o_opt, hw);
+
+        if (retval)
+            if (retval == QUIT)
+                break;
+            else if (op > optlist) {    /* MINUS */
+                wmove(hw, (op - optlist) - 1, 0);
+                op -= 2;
+            }
+            else        /* trying to back up beyond the top */
+            {
+                putchar('\007');
+                wmove(hw, 0, 0);
+                op--;
+            }
+    }
+    /*
+     * Switch back to original screen
+     */
+    mvwaddstr(hw, lines-1, 0, spacemsg);
+    draw(hw);
+    wait_for(' ');
+    restscr(cw);
+    after = FALSE;
+}
+
+/*
+ * parse options from string, usually taken from the environment.
+ * the string is a series of comma seperated values, with booleans
+ * being stated as "name" (true) or "noname" (false), and strings
+ * being "name=....", with the string being defined up to a comma
+ * or the end of the entire option string.
+ */
+
+parse_opts(str)
+register char *str;
+{
+    register char *sp;
+    register OPTION *op;
+    register int len;
+
+    if (*str == '\"')
+       str++;
+
+    while (*str)
+    {
+        /*
+         * Get option name
+         */
+
+        for (sp = str; isalpha(*sp); sp++)
+            continue;
+        len = (char *)sp - str;
+        /*
+         * Look it up and deal with it
+         */
+        for (op = optlist; op < &optlist[NUM_OPTS]; op++)
+            if (EQSTR(str, op->o_name, len))
+            {
+                if (op->o_putfunc == put_bool)  /* if option is a boolean */
+                    *(bool *)op->o_opt = TRUE;
+                else                            /* string option */
+                {
+                    register char *start;
+                    char value[LINELEN];
+
+                    /*
+                     * Skip to start of string value
+                     */
+                    for (str = sp + 1; *str == '=' || *str == ':'; str++)
+                        continue;
+
+                    if (*str == '~')
+                    {
+                        strcpy((char *) value, home);
+                        start = (char *) value + strlen(home);
+                        while (*++str == '/')
+                            continue;
+                    }
+                    else
+                        start = (char *) value;
+                    /*
+                     * Skip to end of string value
+                     */
+                    for (sp = str + 1; *sp && *sp != ',' && *sp != '\"'; sp++)
+                        continue;
+                    strucpy(start, str, (char *) sp - str);
+
+                    /* Put the value into the option field */
+                    if (op->o_putfunc != put_abil) 
+                        strcpy((char *)op->o_opt, value);
+
+                    else if (*op->o_opt == -1) { /* Only init ability once */
+                        register int len = strlen(value);
+                        register int i;
+
+                        for (i=0; i<NUM_CHARTYPES-1; i++) {
+                            if (EQSTR(value, char_class[i].name, len)) {
+                                *op->o_opt = i;
+                                break;
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+            /*
+             * check for "noname" for booleans
+             */
+            else if (op->o_putfunc == put_bool
+              && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
+            {
+                *(bool *)op->o_opt = FALSE;
+                break;
+            }
+
+        /*
+         * skip to start of next option name
+         */
+        while (*sp && !isalpha(*sp))
+            sp++;
+        str = sp;
+    }
+}
+
+
+/*
+ * print the default attributes
+ */
+
+/* put_default(b, win)
+ * bool *b;
+ * WINDOW *win;
+ * {
+ *     waddstr(win, *b ? "True" : "False");
+ * }
+ */
+
+/*
+ * print the character type
+ */
+
+put_abil(ability, win)
+int *ability;
+WINDOW *win;
+{
+    waddstr(win, char_class[*ability].name);
+}
+
+/*
+ * print out the quest
+ */
+
+put_quest(quest, win)
+int *quest;
+WINDOW *win;
+{
+    waddstr(win, rel_magic[*quest].mi_name);
+}
+
+/*
+ * put out a boolean
+ */
+
+put_bool(b, win)
+bool    *b;
+WINDOW *win;
+{
+    waddstr(win, *b ? "True" : "False");
+}
+
+/*
+ * put out a string
+ */
+
+put_str(str, win)
+char *str;
+WINDOW *win;
+{
+    waddstr(win, str);
+}
+