diff --git a/include/wincurs.h b/include/wincurs.h index cb43f3729..ddf026483 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -45,6 +45,12 @@ extern WINDOW *mapwin, *statuswin, *messagewin; /* Main windows */ # endif #endif +#if !defined(A_LEFTLINE) && defined(A_LEFT) +#define A_LEFTLINE A_LEFT +#endif +#if !defined(A_RIGHTLINE) && defined(A_RIGHT) +#define A_RIGHTLINE A_RIGHT +#endif typedef enum orient_type { @@ -158,6 +164,7 @@ extern void curses_rtrim(char *str); extern int curses_get_count(int first_digit); extern int curses_convert_attr(int attr); extern int curses_read_attrs(char *attrs); +extern char *curses_fmt_attrs(char *); extern int curses_convert_keys(int key); extern int curses_get_mouse(int *mousex, int *mousey, int *mod); diff --git a/src/options.c b/src/options.c index 64d8d9dea..2c5e463ef 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.355 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1551222973 2019/02/26 23:16:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.356 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -29,6 +29,7 @@ NEARDATA struct instance_flags iflags; /* provide linkage */ #ifdef CURSES_GRAPHICS extern int curses_read_attrs(char *attrs); +extern char *curses_fmt_attrs(char *); #endif enum window_option_types { @@ -131,9 +132,9 @@ static struct Bool_Opt { { "flush", (boolean *) 0, FALSE, SET_IN_FILE }, #endif { "force_invmenu", &iflags.force_invmenu, FALSE, SET_IN_GAME }, - { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, + { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, /*WC2*/ { "goldX", &iflags.goldX, FALSE, SET_IN_GAME }, - { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME}, + { "guicolor", &iflags.wc2_guicolor, TRUE, SET_IN_GAME}, /*WC2*/ { "help", &flags.help, TRUE, SET_IN_GAME }, { "herecmd_menu", &iflags.herecmd_menu, FALSE, SET_IN_GAME }, { "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/ @@ -209,7 +210,7 @@ static struct Bool_Opt { { "showscore", (boolean *) 0, FALSE, SET_IN_FILE }, #endif { "silent", &flags.silent, TRUE, SET_IN_GAME }, - { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE }, + { "softkeyboard", &iflags.wc2_softkeyboard, FALSE, SET_IN_FILE }, /*WC2*/ { "sortpack", &flags.sortpack, TRUE, SET_IN_GAME }, { "sparkle", &flags.sparkle, TRUE, SET_IN_GAME }, { "splash_screen", &iflags.wc_splash_screen, TRUE, DISP_IN_GAME }, /*WC*/ @@ -228,7 +229,7 @@ static struct Bool_Opt { #ifdef DEBUG { "travel_debug", &iflags.trav_debug, FALSE, SET_IN_WIZGAME }, /*hack.c*/ #endif - { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, + { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, /*WC2*/ #ifdef WIN32 { "use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME }, /*WC*/ #else @@ -243,7 +244,7 @@ static struct Bool_Opt { { "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME }, { "whatis_moveskip", &iflags.getloc_moveskip, FALSE, SET_IN_GAME }, { "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME }, - { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, + { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, /*WC2*/ #ifdef ZEROCOMP { "zerocomp", &iflags.zerocomp, #if defined(COMPRESS) || defined(ZLIB_COMP) @@ -344,19 +345,18 @@ static struct Comp_Opt { #ifdef CHANGE_COLOR { "palette", #ifndef WIN32 - "palette (00c/880/-fff is blue/yellow/reverse white)", 15, - SET_IN_GAME }, + "palette (00c/880/-fff is blue/yellow/reverse white)", 15, SET_IN_GAME #else - "palette (adjust an RGB color in palette (color-R-G-B)", 15, - SET_IN_FILE }, + "palette (adjust an RGB color in palette (color-R-G-B)", 15, SET_IN_FILE #endif + }, #if defined(MAC) { "hicolor", "same as palette, only order is reversed", 15, SET_IN_FILE }, #endif #endif { "paranoid_confirmation", "extra prompting in certain situations", 28, SET_IN_GAME }, - { "petattr", "attributes for highlighting pets", 12, SET_IN_FILE }, + { "petattr", "attributes for highlighting pets", 88, SET_IN_GAME }, { "pettype", "your preferred initial pet type", 4, DISP_IN_GAME }, { "pickup_burden", "maximum burden picked up before prompt", 20, SET_IN_GAME }, @@ -409,6 +409,9 @@ static struct Comp_Opt { #endif { "suppress_alert", "suppress alerts about version-specific features", 8, SET_IN_GAME }, + /* term_cols,term_rows -> WC2_TERM_SIZE (6: room to format 1..32767) */ + { "term_cols", "number of columns", 6, SET_IN_FILE }, /*WC2*/ + { "term_rows", "number of rows", 6, SET_IN_FILE }, /*WC2*/ { "tile_width", "width of tiles", 20, DISP_IN_GAME }, /*WC*/ { "tile_height", "height of tiles", 20, DISP_IN_GAME }, /*WC*/ { "tile_file", "name of tile file", 70, DISP_IN_GAME }, /*WC*/ @@ -430,6 +433,7 @@ static struct Comp_Opt { { "whatis_filter", "filter coordinate locations when targeting next or previous", 1, SET_IN_GAME }, + { "windowborders", "1 (on), 2 (off), 3 (auto)", 9, DISP_IN_GAME }, /*WC2*/ { "windowcolors", "the foreground/background colors of windows", /*WC*/ 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, @@ -3325,6 +3329,7 @@ boolean tinitial, tfrom_file; return retval; } #endif /* VIDEOSHADES */ + #ifdef MSDOS #ifdef NO_TERMS /* video:string -- must be after longer tests */ @@ -3447,8 +3452,8 @@ boolean tinitial, tfrom_file; if (negated) { bad_negation(fullname, FALSE); return FALSE; - } else { #if defined(WIN32) + } else { op = string_for_opt(opts, 0); if (!op) return FALSE; @@ -3593,29 +3598,34 @@ boolean tinitial, tfrom_file; } return retval; } + #ifdef CURSES_GRAPHICS /* WINCAP2 - * term_cols:amount */ + * term_cols:amount or term_rows:amount */ fullname = "term_cols"; - if (match_optname(opts, fullname, sizeof "term_cols" - 1, TRUE)) { - op = string_for_opt(opts, negated); - iflags.wc2_term_cols = atoi(op); - if (negated) { - bad_negation(fullname, FALSE); - return FALSE; - } - return retval; - } + if (match_optname(opts, fullname, 8, TRUE) + /* alternate spelling */ + || match_optname(opts, "term_columns", 9, TRUE) + /* different option but identical handlng */ + || (fullname = "term_rows", match_optname(opts, fullname, 8, TRUE))) { + long ltmp; - /* WINCAP2 - * term_rows:amount */ - fullname = "term_rows"; - if (match_optname(opts, fullname, sizeof "term_rows" - 1, TRUE)) { op = string_for_opt(opts, negated); - iflags.wc2_term_rows = atoi(op); + ltmp = atol(op); if (negated) { bad_negation(fullname, FALSE); - return FALSE; + retval = FALSE; + + /* this just checks atol() sanity, not logical window size sanity */ + } else if (ltmp <= 0L || ltmp >= (long) LARGEST_INT) { + config_error_add("Invalid %s: %ld", fullname, ltmp); + retval = FALSE; + + } else { + if (!strcmp(fullname, "term_rows")) + iflags.wc2_term_rows = (int) ltmp; + else /* !strcmp(fullname, "term_cols") */ + iflags.wc2_term_cols = (int) ltmp; } return retval; } @@ -3625,22 +3635,31 @@ boolean tinitial, tfrom_file; fullname = "petattr"; if (match_optname(opts, fullname, sizeof "petattr" - 1, TRUE)) { op = string_for_opt(opts, negated); - if (op && !negated) { + if (op && negated) { + bad_negation(fullname, TRUE); + retval = FALSE; + } else if (op) { #ifdef CURSES_GRAPHICS - iflags.wc2_petattr = curses_read_attrs(op); - if (!curses_read_attrs(op)) { + int itmp = curses_read_attrs(op); + + if (itmp == -1) { config_error_add("Unknown %s parameter '%s'", fullname, opts); - return FALSE; - } + retval = FALSE; + } else + iflags.wc2_petattr = itmp; #else /* non-curses windowports will not use this flag anyway * but the above will not compile if we don't have curses. * Just set it to a sensible default: */ - iflags.wc2_petattr = ATR_INVERSE + iflags.wc2_petattr = ATR_INVERSE; #endif } else if (negated) { - bad_negation(fullname, TRUE); - return FALSE; + iflags.wc2_petattr = ATR_NONE; + } + if (retval) { + iflags.hilite_pet = (iflags.wc2_petattr != ATR_NONE); + if (!initial) + need_redraw = TRUE; } return retval; } @@ -3648,28 +3667,31 @@ boolean tinitial, tfrom_file; /* WINCAP2 * windowborders:n */ fullname = "windowborders"; - if (match_optname(opts, fullname, sizeof "windowborders" - 1, TRUE)) { + if (match_optname(opts, fullname, 10, TRUE)) { op = string_for_opt(opts, negated); if (negated && op) { bad_negation(fullname, TRUE); - return FALSE; + retval = FALSE; } else { + int itmp; + if (negated) - iflags.wc2_windowborders = 2; /* Off */ + itmp = 2; /* Off */ else if (!op) - iflags.wc2_windowborders = 1; /* On */ - else /* Value supplied */ - iflags.wc2_windowborders = atoi(op); - if ((iflags.wc2_windowborders > 3) - || (iflags.wc2_windowborders < 1)) { - iflags.wc2_windowborders = 0; - config_error_add("Badoption - windowborders %s.", opts); - return FALSE; + itmp = 1; /* On */ + else /* Value supplied; expect 1 (on), 2 (off), or 3 (auto) */ + itmp = atoi(op); + + if (itmp < 1 || itmp > 3) { + config_error_add("Invalid %s: %s.", fullname, opts); + retval = FALSE; + } else { + iflags.wc2_windowborders = itmp; } } return retval; } -#endif +#endif /* CURSES_GRAPHICS */ /* menustyle:traditional or combination or full or partial */ fullname = "menustyle"; @@ -5592,6 +5614,18 @@ char *buf; if (flags.paranoia_bits & paranoia[i].flagmask) Sprintf(eos(tmpbuf), " %s", paranoia[i].argname); Strcpy(buf, tmpbuf[0] ? &tmpbuf[1] : "none"); + } else if (!strcmp(optname, "petattr")) { +#ifdef CURSES_GRAPHICS + if (WINDOWPORT("curses")) { + char tmpbuf[QBUFSZ]; + + Strcpy(buf, curses_fmt_attrs(tmpbuf)); + } else +#endif + if (iflags.wc2_petattr != 0) + Sprintf(buf, "0x%08x", iflags.wc2_petattr); + else + Strcpy(buf, defopt); } else if (!strcmp(optname, "pettype")) { Sprintf(buf, "%s", (preferred_pet == 'c') ? "cat" : (preferred_pet == 'd') ? "dog" @@ -5674,7 +5708,6 @@ char *buf; symset[PRIMARY].name ? symset[PRIMARY].name : "default"); if (currentgraphics == PRIMARY && symset[PRIMARY].name) Strcat(buf, ", active"); -#ifdef CURSES_GRAPHICS } else if (!strcmp(optname, "term_cols")) { if (iflags.wc2_term_cols) Sprintf(buf, "%d", iflags.wc2_term_cols); @@ -5682,10 +5715,9 @@ char *buf; Strcpy(buf, defopt); } else if (!strcmp(optname, "term_rows")) { if (iflags.wc2_term_rows) - Sprintf(buf, "%d",iflags.wc2_term_rows); + Sprintf(buf, "%d", iflags.wc2_term_rows); else Strcpy(buf, defopt); -#endif } else if (!strcmp(optname, "tile_file")) { Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt); @@ -6433,9 +6465,11 @@ static struct wc_Opt wc2_options[] = { { "status hilite rules", WC2_HILITE_STATUS }, /* statushilites doesn't have its own bit */ { "statushilites", WC2_HILITE_STATUS }, -#ifdef CURSES_GRAPHICS - {"windowborders", WC2_WINDOWBORDERS}, -#endif + { "term_cols", WC2_TERM_SIZE }, + { "term_rows", WC2_TERM_SIZE }, + { "petattr", WC2_PETATTR }, + { "guicolor", WC2_GUICOLOR }, + { "windowborders", WC2_WINDOWBORDERS }, { (char *) 0, 0L } }; diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 5f53df4ed..1cdc62a18 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -835,11 +835,15 @@ curses_init_options() iflags.wc2_windowborders = 3; /* Set to auto if not specified */ } - if (!iflags.wc2_petattr) { - iflags.wc2_petattr = A_REVERSE; - } else { /* Pet attribute specified, so hilite_pet should be true */ - + /* fix up pet highlighting */ + if (iflags.wc2_petattr == -1) /* shouldn't happen */ + iflags.wc2_petattr = A_NORMAL; + if (iflags.wc2_petattr != A_NORMAL) { + /* Pet attribute specified, so hilite_pet should be true */ iflags.hilite_pet = TRUE; + } else if (iflags.hilite_pet) { + /* pet highlighting specified, so don't leave petattr at A_NORMAL */ + iflags.wc2_petattr = A_REVERSE; } #ifdef NCURSES_MOUSE_VERSION diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index b4b3764d7..63bf2e03d 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -47,7 +47,7 @@ curses_read_char() ch = curses_convert_keys(ch); if (ch == 0) { - ch = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ + ch = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ } #if defined(ALT_0) && defined(ALT_9) /* PDCurses, maybe others */ if ((ch >= ALT_0) && (ch <= ALT_9)) { @@ -66,11 +66,11 @@ curses_read_char() #ifdef KEY_RESIZE /* Handle resize events via get_nh_event, not this code */ if (ch == KEY_RESIZE) { - ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */ + ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */ } #endif - if (counting && !isdigit(ch)) { /* Dismiss count window if necissary */ + if (counting && !isdigit(ch)) { /* Dismiss count window if necissary */ curses_count_window(NULL); curses_refresh_nethack_windows(); } @@ -249,7 +249,7 @@ curses_num_lines(const char *str, int width) if (last_space == 0) { /* No spaces found */ last_space = count - 1; } - for (count = (last_space + 1); (size_t) count < strlen(substr); count++) { + for (count = (last_space + 1); count < (int) strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; @@ -389,7 +389,7 @@ curses_str_remainder(const char *str, int width, int line_num) if (substr[count] == '\0') { break; } - for (count = (last_space + 1); (size_t) count < strlen(substr); count++) { + for (count = (last_space + 1); count < (int) strlen(substr); count++) { tmpstr[count - (last_space + 1)] = substr[count]; } tmpstr[count - (last_space + 1)] = '\0'; @@ -682,44 +682,87 @@ curses_convert_attr(int attr) /* Map letter attributes from a string to bitmask. Return mask on -success, or 0 if not found */ + success (might be 0), or -1 if not found. */ int curses_read_attrs(char *attrs) { int retattr = 0; - if (strchr(attrs, 'b') || strchr(attrs, 'B')) { - retattr = retattr | A_BOLD; - } - if (strchr(attrs, 'i') || strchr(attrs, 'I')) { - retattr = retattr | A_REVERSE; - } - if (strchr(attrs, 'u') || strchr(attrs, 'U')) { - retattr = retattr | A_UNDERLINE; - } - if (strchr(attrs, 'k') || strchr(attrs, 'K')) { - retattr = retattr | A_BLINK; - } + if (!attrs || !*attrs) + return A_NORMAL; + + if (strchr(attrs, 'b') || strchr(attrs, 'B')) + retattr |= A_BOLD; + if (strchr(attrs, 'i') || strchr(attrs, 'I')) /* inverse */ + retattr |= A_REVERSE; + if (strchr(attrs, 'u') || strchr(attrs, 'U')) + retattr |= A_UNDERLINE; + if (strchr(attrs, 'k') || strchr(attrs, 'K')) + retattr |= A_BLINK; + if (strchr(attrs, 'd') || strchr(attrs, 'D')) + retattr |= A_DIM; #ifdef A_ITALIC - if (strchr(attrs, 't') || strchr(attrs, 'T')) { - retattr = retattr | A_ITALIC; - } -#endif -#ifdef A_RIGHTLINE - if (strchr(attrs, 'r') || strchr(attrs, 'R')) { - retattr = retattr | A_RIGHTLINE; - } + if (strchr(attrs, 't') || strchr(attrs, 'T')) + retattr |= A_ITALIC; #endif #ifdef A_LEFTLINE - if (strchr(attrs, 'l') || strchr(attrs, 'L')) { - retattr = retattr | A_LEFTLINE; - } + if (strchr(attrs, 'l') || strchr(attrs, 'L')) + retattr |= A_LEFTLINE; #endif - +#ifdef A_RIGHTLINE + if (strchr(attrs, 'r') || strchr(attrs, 'R')) + retattr |= A_RIGHTLINE; +#endif + if (retattr == 0) { + /* still default; check for none/normal */ + if (strchr(attrs, 'n') || strchr(attrs, 'N')) + retattr = A_NORMAL; + else + retattr = -1; /* error */ + } return retattr; } +/* format iflags.wc2_petattr into "+a+b..." for set bits a, b, ... + (used by core's 'O' command; return value points past leading '+') */ +char * +curses_fmt_attrs(outbuf) +char *outbuf; +{ + int attr = iflags.wc2_petattr; + + outbuf[0] = '\0'; + if (attr == A_NORMAL) { + Strcpy(outbuf, "+N(None)"); + } else { + if (attr & A_BOLD) + Strcat(outbuf, "+B(Bold)"); + if (attr & A_REVERSE) + Strcat(outbuf, "+I(Inverse)"); + if (attr & A_UNDERLINE) + Strcat(outbuf, "+U(Underline)"); + if (attr & A_BLINK) + Strcat(outbuf, "+K(blinK)"); + if (attr & A_DIM) + Strcat(outbuf, "+D(Dim)"); +#ifdef A_ITALIC + if (attr & A_ITALIC) + Strcat(outbuf, "+T(iTalic)"); +#endif +#ifdef A_LEFTLINE + if (attr & A_LEFTLINE) + Strcat(outbuf, "+L(Left line)"); +#endif +#ifdef A_RIGHTLINE + if (attr & A_RIGHTLINE) + Strcat(outbuf, "+R(Right line)"); +#endif + } + if (!*outbuf) + Sprintf(outbuf, "+unknown [%d]", attr); + return &outbuf[1]; +} /* Convert special keys into values that NetHack can understand. Currently this is limited to arrow keys, but this may be expanded. */ @@ -827,7 +870,7 @@ curses_get_mouse(int *mousex, int *mousey, int *mod) #ifdef NCURSES_MOUSE_VERSION MEVENT event; - if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ + if (getmouse(&event) == OK) { /* When the user clicks left mouse button */ if (event.bstate & BUTTON1_CLICKED) { /* See if coords are in map window & convert coords */ if (wmouse_trafo(mapwin, &event.y, &event.x, TRUE)) { diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 364901267..392d67d11 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -27,6 +27,7 @@ void curses_rtrim(char *str); int curses_get_count(int first_digit); int curses_convert_attr(int attr); int curses_read_attrs(char *attrs); +char *curses_fmt_attrs(char *); int curses_convert_keys(int key); int curses_get_mouse(int *mousex, int *mousey, int *mod);