Mercurial > hg > early-roguelike
diff urogue/options.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children | ac42afd962e4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/options.c Tue Jan 31 19:56:04 2017 -0500 @@ -0,0 +1,519 @@ +/* + options.c - This file has all the code for the option command + + UltraRogue: The Ultimate Adventure in the Dungeons of Doom + Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka + 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. +*/ + +#include <string.h> +#include <ctype.h> +#include "rogue.h" + +#define NUM_OPTS (sizeof optlist / sizeof (OPTION)) +#define EQSTR(a, b, c) (strncmp(a, b, c) == 0) + +/* description of an option and what to do with it */ +static OPTION optlist[] = +{ +{"jump","Show position only at end of run (jump): ", &jump,put_bool,get_bool}, +{"inven","Style of inventories (inven): ", &inv_type, put_inv, get_inv}, +{"askme","Ask me about unidentified things (askme): ",&askme,put_bool,get_bool}, +{"doorstop","Stop running when adjacent (doorstop): ",&doorstop,put_bool,get_bool}, +{"name", "Name (name): ", &whoami, put_str, get_str}, +{"fruit", "Fruit (fruit): ", &fruit, put_str, get_str}, +{"file", "Save file (file): ", &file_name, put_str, get_str}, +{"score", "Score file (score): ", &score_file, put_str, get_str}, +{"class", "Character class (class): ",&char_type, put_abil, get_abil} +}; + +/* + option() + print and then set options from the terminal +*/ + +void +option(void) +{ + OPTION *op; + 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, (int)(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); + wrefresh(hw); + wait_for(' '); + clearok(cw, TRUE); + touchwin(cw); +} + +/* + put_bool() + put out a boolean +*/ + +void +put_bool(opt_arg *opt, WINDOW *win) +{ + waddstr(win, *opt->iarg ? "True" : "False"); +} + +/* + put_str() + put out a string +*/ + +void +put_str(opt_arg *opt, WINDOW *win) +{ + waddstr(win, opt->str); +} + +/* + put_abil() + print the character type +*/ + +void +put_abil(opt_arg *opt, WINDOW *win) +{ + char *abil; + + switch(*opt->iarg) + { + case C_FIGHTER: + abil = "Fighter"; + break; + case C_MAGICIAN: + abil = "Magic User"; + break; + case C_CLERIC: + abil = "Cleric"; + break; + case C_THIEF: + abil = "Thief"; + break; + case C_PALADIN: + abil = "Paladin"; + break; + case C_RANGER: + abil = "Ranger"; + break; + case C_ILLUSION: + abil = "Illusionist"; + break; + case C_ASSASIN: + abil = "Assasin"; + break; + case C_NINJA: + abil = "Ninja"; + break; + case C_DRUID: + abil = "Druid"; + break; + default: + abil = "(unknown)"; + } + waddstr(win, abil); +} + + +/* + get_bool() + allow changing a boolean option and print it out +*/ + +int +get_bool(opt_arg *opt, WINDOW *win) +{ + int oy, ox; + int op_bad; + + op_bad = TRUE; + getyx(win, oy, ox); + waddstr(win, *opt->iarg ? "True" : "False"); + + while(op_bad) + { + wmove(win, oy, ox); + wrefresh(win); + + switch (readcharw(win)) + { + case 't': + case 'T': + *opt->iarg = TRUE; + op_bad = FALSE; + break; + + case 'f': + case 'F': + *opt->iarg = 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, *opt->iarg ? "True" : "False"); + waddch(win, '\n'); + + return(NORM); +} + +/* + get_str() + set a string option +*/ + +int +get_str(opt_arg *opt, WINDOW *win) +{ + return( get_string(opt->str, win) ); +} + +/* + get_abil() + The ability field is read-only +*/ + +int +get_abil(opt_arg *opt, WINDOW *win) +{ + int oy, ox, ny, nx; + int op_bad; + + op_bad = TRUE; + getyx(win, oy, ox); + put_abil(opt, win); + getyx(win, ny, nx); + + while(op_bad) + { + wmove(win, oy, ox); + wrefresh(win); + + switch(readcharw(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); +} + + +/* + parse_opts() + 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. + */ + +void +parse_opts(char *str) +{ + char *sp; + const OPTION *op; + size_t len; + + while (*str) + { + for (sp = str; isalpha(*sp); sp++) + continue; + + len = 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) + *op->o_opt.iarg = TRUE; + else /* string option */ + { + char *start; + char value[80]; + + /* Skip to start of string value */ + + for (str = sp + 1; *str == '='; str++) + continue; + + start = (char *) value; + + /* Skip to end of string value */ + + for (sp = str + 1; *sp && *sp != ','; sp++) + continue; + + strncpy(start, str, sp - str); + + /* Put the value into the option field */ + + if (op->o_putfunc != put_abil && + op->o_putfunc != put_inv) + strcpy(op->o_opt.str, value); + + if (op->o_putfunc == put_inv) + { + int *opt = op->o_opt.iarg; + + len = strlen(value); + + if (isupper(value[0])) + value[0] = (char) tolower(value[0]); + if (EQSTR(value, "overwrite",len)) + *opt = INV_OVER; + if (EQSTR(value, "slow", len)) + *opt = INV_SLOW; + if (EQSTR(value, "clear", len)) + *opt = INV_CLEAR; + } + else if (*op->o_opt.iarg == -1) + { + int *opt = op->o_opt.iarg; + + len = strlen(value); + + if (isupper(value[0])) + value[0] = (char) tolower(value[0]); + if (EQSTR(value, "fighter", len)) + *opt = C_FIGHTER; + else if (EQSTR(value, "magic", min(len, 5))) + *opt = C_MAGICIAN; + else if (EQSTR(value, "illus", min(len, 5))) + *opt = C_ILLUSION; + else if (EQSTR(value, "cleric", len)) + *opt = C_CLERIC; + else if (EQSTR(value, "thief", len)) + *opt = C_THIEF; + else if (EQSTR(value, "paladin", len)) + *opt = C_PALADIN; + else if (EQSTR(value, "ranger", len)) + *opt = C_RANGER; + else if (EQSTR(value, "assasin", len)) + *opt = C_ASSASIN; + else if (EQSTR(value, "druid", len)) + *opt = C_DRUID; + else if (EQSTR(value, "ninja", len)) + *opt = C_NINJA; + } + } + break; + } + else if (op->o_putfunc == put_bool + && EQSTR(str, "no", 2) && + EQSTR(str + 2, op->o_name, len - 2)) + { + *op->o_opt.iarg = FALSE; + break; + } + + /* skip to start of next option name */ + + while (*sp && !isalpha(*sp)) + sp++; + + str = sp; + } +} + +/* + put_inv() + print the inventory type +*/ + +void +put_inv(opt_arg *opt, WINDOW *win) +{ + char *style; + + switch(*opt->iarg) + { + case INV_OVER: + style = "Overwrite"; + break; + + case INV_SLOW: + style = "Slow"; + break; + + case INV_CLEAR: + style = "Clear Screen"; + break; + + default: + style = "(unknown)"; + } + + waddstr(win, style); +} + +/* + get_inv() + The inventory field. +*/ + +int +get_inv(opt_arg *opt, WINDOW *win) +{ + int oy, ox, ny, nx; + int op_bad; + + op_bad = TRUE; + getyx(win, oy, ox); + put_inv(opt, win); + getyx(win, ny, nx); + + while(op_bad) + { + wmove(win, oy, ox); + wrefresh(win); + + switch(readcharw(win)) + { + case '\n': + case '\r': + op_bad = FALSE; + break; + + case '\033': + case '\007': + return(QUIT); + + case '-': + return(MINUS); + + case 'O': + case 'o': + *opt->iarg = INV_OVER; + op_bad = FALSE; + break; + + case 'S': + case 's': + *opt->iarg = INV_SLOW; + op_bad = FALSE; + break; + + case 'C': + case 'c': + *opt->iarg = INV_CLEAR; + op_bad = FALSE; + break; + + default: + mvwaddstr(win, ny, nx + 5, "(Use: o, s, or c)"); + } + } + + wmove(win, oy, ox); + wclrtoeol(win); + + switch(*opt->iarg) + { + case INV_SLOW: + waddstr(win, "Slow\n"); + break; + + case INV_CLEAR: + waddstr(win, "Clear Screen\n"); + break; + + case INV_OVER: + waddstr(win, "Overwrite\n"); + break; + + default: + waddstr(win, "Unknown\n"); + break; + } + + return(NORM); +}