From 0470065b47de87ed4ea239d8c7fdba8c10e55452 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 22 Oct 2018 21:23:12 +0300 Subject: [PATCH] X11: TTY-style status lines Set X resource NetHack*fancy_status: False to enable the TTY-style status lines. Default is the fancy status. This patch is somewhat unfinished - even though the TTY-style status allow for status hilites, the colors don't work correctly yet. Also changes the fancy status to use the windowport notification code. --- include/extern.h | 1 + include/winX.h | 5 + src/botl.c | 10 + win/X11/NetHack.ad | 4 + win/X11/winX.c | 15 +- win/X11/winstat.c | 854 +++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 818 insertions(+), 71 deletions(-) diff --git a/include/extern.h b/include/extern.h index e73c931a6..27699c8bf 100644 --- a/include/extern.h +++ b/include/extern.h @@ -145,6 +145,7 @@ E int NDECL(getbones); /* ### botl.c ### */ +E const char *FDECL(bl_idx_to_fldname, (int)); E char *NDECL(do_statusline1); E void NDECL(check_gold_symbol); E char *NDECL(do_statusline2); diff --git a/include/winX.h b/include/winX.h index 3fe217107..9a9b8ce75 100644 --- a/include/winX.h +++ b/include/winX.h @@ -254,6 +254,7 @@ E boolean plsel_ask_name; typedef struct { Boolean slow; /* issue prompts between map and message wins */ + Boolean fancy_status; /* use "fancy" status vs. TTY-style status */ Boolean autofocus; /* grab pointer focus for popup windows */ Boolean message_line; /* separate current turn mesgs from prev ones */ Boolean highlight_prompt; /* if 'slow', highlight yn prompts */ @@ -433,6 +434,10 @@ E void FDECL(X11_getlin, (const char *, char *)); E int NDECL(X11_get_ext_cmd); E void FDECL(X11_number_pad, (int)); E void NDECL(X11_delay_output); +E void NDECL(X11_status_init); +E void NDECL(X11_status_finish); +E void FDECL(X11_status_enablefield, (int, const char *, const char *, BOOLEAN_P)); +E void FDECL(X11_status_update, (int, genericptr_t, int, int, int, unsigned long *)); /* other defs that really should go away (they're tty specific) */ E void NDECL(X11_start_screen); diff --git a/src/botl.c b/src/botl.c index fde46e2fb..5d1fe2bcb 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1248,6 +1248,16 @@ static struct fieldid_t { static const char threshold_value[] = "hilite_status threshold ", is_out_of_range[] = " is out of range"; + +const char * +bl_idx_to_fldname(idx) +int idx; +{ + if (idx >= 0 && idx < MAXBLSTATS) + return initblstats[idx].fldname; + return (const char *) 0; +} + /* field name to bottom line index */ STATIC_OVL enum statusfields fldname_to_bl_indx(name) diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index f7ec10613..77274d9ca 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -100,6 +100,10 @@ NetHack*highlight_prompt: False ! has a lot of popups and is almost unplayable without some kind of autofocus. !NetHack*autofocus: True ! + +! True, use a "fancy" style status area vs. TTY-style status lines +!NetHack*fancy_status: False + ! Specify the number of rows and columns of the map window. The default ! is the standard 80x21 window. Note: this _does_not_ change nethack's ! level size, only what you see of it. diff --git a/win/X11/winX.c b/win/X11/winX.c index 834937e93..18a8fb9f5 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -103,7 +103,7 @@ struct window_procs X11_procs = { (WC_COLOR | WC_HILITE_PET | WC_ASCII_MAP | WC_TILED_MAP | WC_PLAYER_SELECTION | WC_PERM_INVENT | WC_MOUSE_SUPPORT), #if defined(STATUS_HILITES) - WC2_FLUSH_STATUS | WC2_RESET_STATUS | + WC2_FLUSH_STATUS | WC2_RESET_STATUS | WC2_HILITE_STATUS | #endif 0L, X11_init_nhwindows, @@ -134,8 +134,8 @@ struct window_procs X11_procs = { genl_outrip, #endif X11_preference_update, X11_getmsghistory, X11_putmsghistory, - genl_status_init, genl_status_finish, genl_status_enablefield, - genl_status_update, + X11_status_init, X11_status_finish, X11_status_enablefield, + X11_status_update, genl_can_suspend_no, /* XXX may not always be correct */ }; @@ -827,9 +827,11 @@ const char *str; toplines[TBUFSZ - 1] = 0; append_message(wp, str); break; +#ifndef STATUS_HILITES case NHW_STATUS: adjust_status(wp, str); break; +#endif case NHW_MAP: impossible("putstr: called on map window \"%s\"", str); break; @@ -1267,6 +1269,8 @@ static XtActionsRec actions[] = { static XtResource resources[] = { { nhStr("slow"), nhStr("Slow"), XtRBoolean, sizeof(Boolean), XtOffset(AppResources *, slow), XtRString, nhStr("True") }, + { nhStr("fancy_status"), nhStr("Fancy_status"), XtRBoolean, sizeof(Boolean), + XtOffset(AppResources *, fancy_status), XtRString, nhStr("True") }, { nhStr("autofocus"), nhStr("AutoFocus"), XtRBoolean, sizeof(Boolean), XtOffset(AppResources *, autofocus), XtRString, nhStr("False") }, { nhStr("message_line"), nhStr("Message_line"), XtRBoolean, @@ -2251,7 +2255,7 @@ static int input_event(exit_condition) int exit_condition; { - if (WIN_STATUS != WIN_ERR) /* hilighting on the fancy status window */ + if (appResources.fancy_status && WIN_STATUS != WIN_ERR) /* hilighting on the fancy status window */ check_turn_events(); if (WIN_MAP != WIN_ERR) /* make sure cursor is not clipped */ check_cursor_visibility(&window_list[WIN_MAP]); @@ -2521,7 +2525,8 @@ init_standard_windows() * after the fancy status widget is realized (above, with the game popup), * but before it is popped up. */ - null_out_status(); + if (appResources.fancy_status) + null_out_status(); /* * Set the map size to its standard size. As with the message window * above, the map window needs to be set to its constrained size until diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 8eb9469bb..6ab189189 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -15,6 +15,7 @@ #endif #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #ifdef PRESERVE_NO_SYSV @@ -31,18 +33,774 @@ #undef PRESERVE_NO_SYSV #endif +#include "xwindow.h" + #include "hack.h" #include "winX.h" +/* + * Fancy status form entry storage indices. + */ +#define F_DUMMY 0 +#define F_STR 1 +#define F_DEX 2 +#define F_CON 3 +#define F_INT 4 +#define F_WIS 5 +#define F_CHA 6 + +#define F_NAME 7 +#define F_DLEVEL 8 +#define F_GOLD 9 +#define F_HP 10 +#define F_MAXHP 11 +#define F_POWER 12 +#define F_MAXPOWER 13 +#define F_AC 14 +#define F_LEVEL 15 +#define F_EXP 16 +#define F_ALIGN 17 +#define F_TIME 18 +#define F_SCORE 19 + +/* status conditions grouped by columns; tty orders these differently */ +#define F_STONE 20 +#define F_SLIME 21 +#define F_STRNGL 22 +#define F_FOODPOIS 23 +#define F_TERMILL 24 + +#define F_HUNGER 25 +#define F_ENCUMBER 26 +#define F_LEV 27 +#define F_FLY 28 +#define F_RIDE 29 + +#define F_BLIND 30 +#define F_DEAF 31 +#define F_STUN 32 +#define F_CONF 33 +#define F_HALLU 34 + +#define NUM_STATS 35 + +static void FDECL(update_fancy_status, (struct xwindow *)); +static void FDECL(update_fancy_status_field, (int)); +static Widget FDECL(create_fancy_status, (Widget, Widget)); +static void FDECL(destroy_fancy_status, (struct xwindow *)); +static void FDECL(create_status_window_fancy, (struct xwindow *, BOOLEAN_P, Widget)); +static void FDECL(create_status_window_tty, (struct xwindow *, BOOLEAN_P, Widget)); +static void FDECL(destroy_status_window_fancy, (struct xwindow *)); +static void FDECL(destroy_status_window_tty, (struct xwindow *)); +static void FDECL(adjust_status_fancy, (struct xwindow *, const char *)); +static void FDECL(adjust_status_tty, (struct xwindow *, const char *)); + +extern const char *status_fieldfmt[MAXBLSTATS]; +extern char *status_vals[MAXBLSTATS]; +extern boolean status_activefields[MAXBLSTATS]; +static long X11_condition_bits; +static int X11_status_colors[MAXBLSTATS]; +static int hpbar_percent, hpbar_color; + +#define X11_NUM_STATUS_LINES 2 +#define X11_NUM_STATUS_FIELD 15 + +static enum statusfields X11_fieldorder[X11_NUM_STATUS_LINES][X11_NUM_STATUS_FIELD] = { + { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN, + BL_SCORE, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, + BL_FLUSH }, + { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, + BL_AC, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_HUNGER, + BL_CAP, BL_CONDITION, BL_FLUSH } +}; + +static boolean X11_labels_created = FALSE; +static Widget X11_status_widget; +static Widget X11_status_labels[MAXBLSTATS]; +static Widget X11_cond_labels[32]; /* Ugh */ + +static Pixel X11_colors[16]; +static Pixel X11_status_widget_fg, X11_status_widget_bg; + + +int +condcolor(bm, bmarray) +long bm; +unsigned long *bmarray; +{ + int i; + + if (bm && bmarray) + for (i = 0; i < CLR_MAX; ++i) { + if (bmarray[i] && (bm & bmarray[i])) + return i; + } + return NO_COLOR; +} + +int +condattr(bm, bmarray) +long bm; +unsigned long *bmarray; +{ + int attr = 0; + int i; + + if (bm && bmarray) { + for (i = HL_ATTCLR_DIM; i < BL_ATTCLR_MAX; ++i) { + if (bmarray[i] && (bm & bmarray[i])) { + switch(i) { + case HL_ATTCLR_DIM: + attr |= HL_DIM; + break; + case HL_ATTCLR_BLINK: + attr |= HL_BLINK; + break; + case HL_ATTCLR_ULINE: + attr |= HL_ULINE; + break; + case HL_ATTCLR_INVERSE: + attr |= HL_INVERSE; + break; + case HL_ATTCLR_BOLD: + attr |= HL_BOLD; + break; + } + } + } + } + return attr; +} + +void +X11_status_init() +{ +#ifdef STATUS_HILITES + int i; + + for (i = 0; i < MAXBLSTATS; ++i) + X11_status_colors[i] = NO_COLOR; /* no color */ + X11_condition_bits = 0L; + hpbar_percent = 0, hpbar_color = NO_COLOR; +#endif /* STATUS_HILITES */ + /* let genl_status_init do most of the initialization */ + genl_status_init(); +} + +void +X11_status_finish() +{ + /* nothing */ +} + +void +X11_status_enablefield(fieldidx, nm, fmt, enable) +int fieldidx; +const char *nm; +const char *fmt; +boolean enable; +{ + genl_status_enablefield(fieldidx, nm, fmt, enable); +} + + +int +cond_bm2idx(bm) +unsigned long bm; +{ + int i; + for (i = 0; i < 32; i++) + if ((1 << i) == bm) + return i; + return -1; +} + +void +MaybeDisplayCond(bm, colormasks, text) +unsigned long bm; +unsigned long *colormasks; +const char *text; +{ + int idx = cond_bm2idx(bm); + Widget label; + Arg args[10]; + Cardinal num_args; + Pixel fg = X11_status_widget_fg, bg = X11_status_widget_bg; + Dimension lbl_wid; + Dimension lbl_hei; + Dimension lbl_border_wid; + Dimension lbl_iwidth; + + if (idx < 0) + return; + + label = X11_cond_labels[idx]; + if ((X11_condition_bits & bm)) { + int attrmask, coloridx; + XFontStruct *font; + Position lbl_x; + Position lbl_y; +#ifdef TEXTCOLOR + coloridx = condcolor(bm, colormasks); +#endif + attrmask = condattr(bm, colormasks); + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNfont), &font); num_args++; + XtSetArg(args[num_args], nhStr(XtNx), &lbl_x); num_args++; + XtSetArg(args[num_args], nhStr(XtNy), &lbl_y); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; + XtSetArg(args[num_args], nhStr(XtNheight), &lbl_hei); num_args++; + XtSetArg(args[num_args], nhStr(XtNinternalWidth), &lbl_iwidth); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), &lbl_border_wid); num_args++; + XtGetValues(label, args, num_args); + + if (text && *text) + lbl_wid = lbl_iwidth + font->max_bounds.width * strlen(text); + else + lbl_wid = 1; + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNlabel), (text && *text) ? text : ""); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++; + + fg = (coloridx != NO_COLOR) ? X11_colors[coloridx] : X11_status_widget_fg; + if (attrmask & HL_INVERSE) { + Pixel tmppx = fg; + fg = bg; + bg = tmppx; + } + if (fg == bg) + fg = X11_colors[CLR_GRAY]; + + XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; + XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; + XtSetValues(label, args, num_args); + XtResizeWidget(label, lbl_wid, lbl_hei, lbl_border_wid); + } else { + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; + XtSetArg(args[num_args], nhStr(XtNheight), &lbl_hei); num_args++; + XtSetArg(args[num_args], nhStr(XtNinternalWidth), &lbl_iwidth); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), &lbl_border_wid); num_args++; + XtGetValues(label, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), 1); num_args++; + XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; + XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; + XtSetValues(label, args, num_args); + + XtResizeWidget(label, lbl_wid, lbl_hei, lbl_border_wid); + } +} + + +void +X11_status_update_tty(fld, ptr, chg, percent, color, colormasks) +int fld, chg UNUSED, percent UNUSED, color; +genericptr_t ptr; +unsigned long *colormasks; +{ + long *condptr = (long *) ptr; + int i, j, attrmask = 0; +#ifdef TEXTCOLOR + int coloridx = NO_COLOR; +#endif + const char *text = (char *) ptr; + char tmpbuf[BUFSZ]; + static boolean oncearound = FALSE; /* prevent premature partial display */ + int attridx = 0; + + XFontStruct *font; + int direction; + int ascent; + int descent; + XCharStruct overall; + Arg args[10]; + Cardinal num_args; + Position lbl_x; + Position lbl_y; + Dimension lbl_wid; + Dimension lbl_hei; + Dimension lbl_border_wid; + Dimension lbl_iwidth; + Widget label; + Pixel fg = X11_status_widget_fg, bg = X11_status_widget_bg; + + if (fld < BL_RESET || fld >= MAXBLSTATS) + return; + + if ((fld >= 0 && fld < MAXBLSTATS) && !status_activefields[fld]) + return; + + if (fld != BL_FLUSH && fld != BL_RESET) { + if (!status_activefields[fld]) + return; + switch (fld) { + case BL_CONDITION: + X11_condition_bits = *condptr; + oncearound = TRUE; + break; + default: + Sprintf(status_vals[fld], + (fld == BL_TITLE && iflags.wc2_hitpointbar) ? "%-30s" : + status_fieldfmt[fld] ? status_fieldfmt[fld] : "%s", + text); +#ifdef TEXTCOLOR + X11_status_colors[fld] = color; +#else + X11_status_colors[fld] = NO_COLOR; +#endif + if (iflags.wc2_hitpointbar && fld == BL_HP) { + hpbar_percent = percent; +#ifdef TEXTCOLOR + hpbar_color = color; +#else + hpbar_color = NO_COLOR; +#endif + } + break; + } + if (fld == BL_CONDITION) { + MaybeDisplayCond(BL_MASK_STONE, colormasks, "Stone"); + MaybeDisplayCond(BL_MASK_SLIME, colormasks, "Slime"); + MaybeDisplayCond(BL_MASK_STRNGL, colormasks, "Strngl"); + MaybeDisplayCond(BL_MASK_FOODPOIS, colormasks, "FoodPois"); + MaybeDisplayCond(BL_MASK_TERMILL, colormasks, "TermIll"); + MaybeDisplayCond(BL_MASK_BLIND, colormasks, "Blind"); + MaybeDisplayCond(BL_MASK_DEAF, colormasks, "Deaf"); + MaybeDisplayCond(BL_MASK_STUN, colormasks, "Stun"); + MaybeDisplayCond(BL_MASK_CONF, colormasks, "Conf"); + MaybeDisplayCond(BL_MASK_HALLU, colormasks, "Hallu"); + MaybeDisplayCond(BL_MASK_LEV, colormasks, "Lev"); + MaybeDisplayCond(BL_MASK_FLY, colormasks, "Fly"); + MaybeDisplayCond(BL_MASK_RIDE, colormasks, "Ride"); + } else { + label = X11_status_labels[fld]; + text = status_vals[fld]; + if (fld == BL_GOLD) + text = decode_mixed(tmpbuf, text); + +#ifdef TEXTCOLOR + coloridx = X11_status_colors[fld] & 0x00FF; +#endif + attridx = (X11_status_colors[fld] & 0xFF00) >> 8; + + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNfont), &font); num_args++; + XtSetArg(args[num_args], nhStr(XtNx), &lbl_x); num_args++; + XtSetArg(args[num_args], nhStr(XtNy), &lbl_y); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; + XtSetArg(args[num_args], nhStr(XtNheight), &lbl_hei); num_args++; + XtSetArg(args[num_args], nhStr(XtNinternalWidth), &lbl_iwidth); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), &lbl_border_wid); num_args++; + XtGetValues(label, args, num_args); + + /*raw_printf("font: %i-%i", font->min_bounds.width, font->max_bounds.width);*/ + + if (text && *text) + lbl_wid = lbl_iwidth + font->max_bounds.width * strlen(text); + else + lbl_wid = 1; + + /*raw_printf("1:lbl_wid=%i('%s')", lbl_wid, text);*/ + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNlabel), (text && *text) ? text : ""); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++; + + fg = (coloridx != NO_COLOR) ? X11_colors[coloridx] : X11_status_widget_fg; + if (attridx & HL_INVERSE) { + Pixel tmppx = fg; + fg = bg; + bg = tmppx; + } + + if (fg == bg) + fg = X11_colors[CLR_GRAY]; + + XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; + XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; + XtSetValues(label, args, num_args); + XtResizeWidget(label, lbl_wid, lbl_hei, lbl_border_wid); + } + } else { + int x,y; + for (y = 0; y < X11_NUM_STATUS_LINES; y++) { + Cardinal dx = 0; + for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { + int f = X11_fieldorder[y][x]; + + if (f <= BL_FLUSH) + continue; + if (!status_activefields[f]) + continue; + + if (f == BL_CONDITION) { + int i; + + for (i = 0; i < 32; i++) { + label = X11_cond_labels[i]; + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNx), &lbl_x); num_args++; + XtSetArg(args[num_args], nhStr(XtNy), &lbl_y); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; + XtSetArg(args[num_args], nhStr(XtNheight), &lbl_hei); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), &lbl_border_wid); num_args++; + XtGetValues(label, args, num_args); + + lbl_x = dx; + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++; + XtSetValues(label, args, num_args); + XtConfigureWidget(label, lbl_x, lbl_y, lbl_wid, lbl_hei, lbl_border_wid); + + if (lbl_wid > 1) + dx += lbl_wid; + } + continue; + } + label = X11_status_labels[f]; + + text = status_vals[f]; + if (f == BL_GOLD) + text = decode_mixed(tmpbuf, text); + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNx), &lbl_x); num_args++; + XtSetArg(args[num_args], nhStr(XtNy), &lbl_y); num_args++; + XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; + XtSetArg(args[num_args], nhStr(XtNheight), &lbl_hei); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), &lbl_border_wid); num_args++; + XtGetValues(label, args, num_args); + + lbl_x = dx; + /*raw_printf("2:lbl_wid=%i('%s')", lbl_wid, text);*/ + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++; + XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; + XtSetValues(label, args, num_args); + XtConfigureWidget(label, lbl_x, lbl_y, lbl_wid, lbl_hei, lbl_border_wid); + + dx += lbl_wid; + } + } + } +} + +void +X11_status_update_fancy(fld, ptr, chg, percent, color, colormasks) +int fld, chg UNUSED, percent UNUSED, color; +genericptr_t ptr; +unsigned long *colormasks; +{ + int i; + struct { + int bl, ff; + } bl_to_fancyfield[] = { + { BL_TITLE, F_NAME }, + { BL_STR, F_STR }, + { BL_DX, F_DEX }, + { BL_CO, F_CON }, + { BL_IN, F_INT }, + { BL_WI, F_WIS }, + { BL_CH, F_CHA }, + { BL_ALIGN, F_ALIGN }, + { BL_SCORE, F_SCORE }, + { BL_CAP, F_ENCUMBER }, + { BL_GOLD, F_GOLD }, + { BL_ENE, F_POWER }, + { BL_ENEMAX, F_MAXPOWER }, + { BL_XP, F_LEVEL }, + { BL_AC, F_AC }, + /*{ BL_HD, F_ },*/ + { BL_TIME, F_TIME }, + { BL_HUNGER, F_HUNGER }, + { BL_HP, F_HP }, + { BL_HPMAX, F_MAXHP }, + { BL_LEVELDESC, F_DLEVEL }, + { BL_EXP, F_EXP } + }; + + struct { + long mask; + int ff; + } mask_to_fancyfield[] = { + { BL_MASK_STONE, F_STONE }, + { BL_MASK_SLIME, F_SLIME }, + { BL_MASK_STRNGL, F_STRNGL }, + { BL_MASK_FOODPOIS, F_FOODPOIS }, + { BL_MASK_TERMILL, F_TERMILL }, + { BL_MASK_BLIND, F_BLIND }, + { BL_MASK_DEAF, F_DEAF }, + { BL_MASK_STUN, F_STUN }, + { BL_MASK_CONF, F_CONF }, + { BL_MASK_HALLU, F_HALLU }, + { BL_MASK_LEV, F_LEV }, + { BL_MASK_FLY, F_FLY }, + { BL_MASK_RIDE, F_RIDE } + }; + + if (fld == BL_RESET || fld == BL_FLUSH) { + if (WIN_STATUS != WIN_ERR) { + struct xwindow *wp = &window_list[WIN_STATUS]; + update_fancy_status(wp); + } + return; + } + + if (fld == BL_CONDITION) { + unsigned long mask = (unsigned long) ptr; + + for (i = 0; i < SIZE(mask_to_fancyfield); i++) + if (mask_to_fancyfield[i].mask == mask) + update_fancy_status_field(mask_to_fancyfield[i].ff); + } else { + for (i = 0; i < SIZE(bl_to_fancyfield); i++) + if (bl_to_fancyfield[i].bl == fld) + update_fancy_status_field(bl_to_fancyfield[i].ff); + } +} + +void +X11_status_update(fld, ptr, chg, percent, color, colormasks) +int fld, chg UNUSED, percent UNUSED, color; +genericptr_t ptr; +unsigned long *colormasks; +{ + if (appResources.fancy_status) + X11_status_update_fancy(fld, ptr, chg, percent, color, colormasks); + else + X11_status_update_tty(fld, ptr, chg, percent, color, colormasks); +} + + +void +init_nhcolors(w) +Widget w; +{ + int i; + Display *dpy = XtDisplay(w); + int defscreen = DefaultScreen(dpy); + Colormap cmap = DefaultColormap(dpy, defscreen); + const char * resource2clr[16] = { + XtNblack, + XtNred, + XtNgreen, + XtNbrown, + XtNblue, + XtNmagenta, + XtNcyan, + XtNgray, + XtNforeground, + XtNorange, + XtNbright_green, + XtNyellow, + XtNbright_blue, + XtNbright_magenta, + XtNbright_cyan, + XtNwhite + }; + + for (i = 0; i < SIZE(resource2clr); i++) { + XColor color, ignore; + + if (XAllocNamedColor(dpy, cmap, resource2clr[i], &color, &ignore)) + X11_colors[i] = color.pixel; + else + X11_colors[i] = WhitePixel(dpy, defscreen); + } +} + +Widget +create_tty_status(parent, top) +Widget parent, top; +{ + Widget form; /* The form that surrounds everything. */ + Widget w; + Arg args[16]; + Cardinal num_args; + char buf[32]; + int i, x, y; + Widget testlabel; + + num_args = 0; + if (top != (Widget) 0) { + XtSetArg(args[num_args], nhStr(XtNfromVert), top); + num_args++; + } + XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 0); + num_args++; + XtSetArg(args[num_args], XtNborderWidth, 0); + num_args++; + XtSetArg(args[num_args], XtNwidth, 400); num_args++; + XtSetArg(args[num_args], XtNheight, 100); num_args++; + form = XtCreateManagedWidget("status_viewport", viewportWidgetClass, + parent, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNwidth, 400); num_args++; + XtSetArg(args[num_args], XtNheight, 100); num_args++; + w = XtCreateManagedWidget("status_form", formWidgetClass, + form, args, num_args); + for (y = 0; y < X11_NUM_STATUS_LINES; y++) { + for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { + int fld = X11_fieldorder[y][x]; + char labelname[BUFSZ]; + int prevfld; + if (fld <= BL_FLUSH) + continue; + Sprintf(labelname, "label_%s", bl_idx_to_fldname(fld)); + num_args = 0; + if (y > 0) { + prevfld = X11_fieldorder[y-1][0]; + XtSetArg(args[num_args], nhStr(XtNfromVert), X11_status_labels[prevfld]); num_args++; + } + if (x > 0) { + prevfld = X11_fieldorder[y][x-1]; + XtSetArg(args[num_args], nhStr(XtNfromHoriz), X11_status_labels[prevfld]); num_args++; + } + + XtSetArg(args[num_args], nhStr(XtNhorizDistance), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNvertDistance), 0); num_args++; + + XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNbottomMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNleftMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNrightMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNjustify), XtJustifyLeft); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++; + /* + XtSetArg(args[num_args], nhStr(XtNlabel), bl_idx_to_fldname(fld)); num_args++; + */ + XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; + X11_status_labels[fld] = XtCreateManagedWidget(labelname, + labelWidgetClass, w, + args, num_args); + } + } + + for (i = 0; i < 32; i++) { + char condname[BUFSZ]; + int prevfld; + + Sprintf(condname, "cond_%i", i); + num_args = 0; + + prevfld = X11_fieldorder[0][0]; + XtSetArg(args[num_args], nhStr(XtNfromVert), X11_status_labels[prevfld]); num_args++; + + XtSetArg(args[num_args], nhStr(XtNfromHoriz), + (i == 0) ? X11_status_labels[BL_CONDITION] + : X11_cond_labels[i-1]); num_args++; + + XtSetArg(args[num_args], nhStr(XtNhorizDistance), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNvertDistance), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNbottomMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNleftMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNrightMargin), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNjustify), XtJustifyLeft); num_args++; + XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++; + XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; + X11_cond_labels[i] = XtCreateManagedWidget(condname, + labelWidgetClass, w, + args, num_args); + } + + init_nhcolors(w); + + return w; +} + +void +create_status_window_tty(wp, create_popup, parent) +struct xwindow *wp; /* window pointer */ +boolean create_popup; +Widget parent; +{ + Arg args[10]; + Cardinal num_args; + + wp->type = NHW_STATUS; + X11_status_widget = wp->w = create_tty_status(parent, (Widget) 0); + + num_args = 0; + XtSetArg(args[num_args], nhStr(XtNforeground), &X11_status_widget_fg); num_args++; + XtSetArg(args[num_args], nhStr(XtNbackground), &X11_status_widget_bg); num_args++; + XtGetValues(X11_status_widget, args, num_args); +} + +void +destroy_status_window_tty(wp) +struct xwindow *wp; +{ + /* If status_information is defined, then it a "text" status window. */ + if (wp->status_information) { + if (wp->popup) { + nh_XtPopdown(wp->popup); + if (!wp->keep_window) + XtDestroyWidget(wp->popup), wp->popup = (Widget) 0; + } + free((genericptr_t) wp->status_information); + wp->status_information = 0; + } else { + } + if (!wp->keep_window) + wp->type = NHW_NONE; +} + +void +adjust_status_tty(wp, str) +struct xwindow *wp; +const char *str; +{ + /* nothing */ +} + +void +create_status_window(wp, create_popup, parent) +struct xwindow *wp; /* window pointer */ +boolean create_popup; +Widget parent; +{ + if (appResources.fancy_status) + create_status_window_fancy(wp, create_popup, parent); + else + create_status_window_tty(wp, create_popup, parent); +} + +void +destroy_status_window(wp) +struct xwindow *wp; +{ + if (appResources.fancy_status) + destroy_status_window_fancy(wp); + else + destroy_status_window_tty(wp); +} + +void +adjust_status(wp, str) +struct xwindow *wp; +const char *str; +{ + if (appResources.fancy_status) + adjust_status_fancy(wp, str); + else + adjust_status_tty(wp, str); +} + extern const char *hu_stat[]; /* from eat.c */ extern const char *enc_stat[]; /* from botl.c */ -static void FDECL(update_fancy_status, (struct xwindow *)); -static Widget FDECL(create_fancy_status, (Widget, Widget)); -static void FDECL(destroy_fancy_status, (struct xwindow *)); - void -create_status_window(wp, create_popup, parent) +create_status_window_fancy(wp, create_popup, parent) struct xwindow *wp; /* window pointer */ boolean create_popup; Widget parent; @@ -60,7 +818,7 @@ Widget parent; * window. */ if (!parent) - panic("create_status_window: no parent for fancy status"); + panic("create_status_window_fancy: no parent for fancy status"); wp->status_information = 0; wp->w = create_fancy_status(parent, (Widget) 0); return; @@ -133,7 +891,7 @@ Widget parent; } void -destroy_status_window(wp) +destroy_status_window_fancy(wp) struct xwindow *wp; { /* If status_information is defined, then it a "text" status window. */ @@ -159,7 +917,7 @@ struct xwindow *wp; * + We didn't set stringInPlace on the widget. */ void -adjust_status(wp, str) +adjust_status_fancy(wp, str) struct xwindow *wp; const char *str; { @@ -216,52 +974,6 @@ static Widget FDECL(init_column, (const char *, Widget, Widget, Widget, static void NDECL(fixup_cond_widths); static Widget FDECL(init_info_form, (Widget, Widget, Widget)); -/* - * Form entry storage indices. - */ -#define F_DUMMY 0 -#define F_STR 1 -#define F_DEX 2 -#define F_CON 3 -#define F_INT 4 -#define F_WIS 5 -#define F_CHA 6 - -#define F_NAME 7 -#define F_DLEVEL 8 -#define F_GOLD 9 -#define F_HP 10 -#define F_MAXHP 11 -#define F_POWER 12 -#define F_MAXPOWER 13 -#define F_AC 14 -#define F_LEVEL 15 -#define F_EXP 16 -#define F_ALIGN 17 -#define F_TIME 18 -#define F_SCORE 19 - -/* status conditions grouped by columns; tty orders these differently */ -#define F_STONE 20 -#define F_SLIME 21 -#define F_STRNGL 22 -#define F_FOODPOIS 23 -#define F_TERMILL 24 - -#define F_HUNGER 25 -#define F_ENCUMBER 26 -#define F_LEV 27 -#define F_FLY 28 -#define F_RIDE 29 - -#define F_BLIND 30 -#define F_DEAF 31 -#define F_STUN 32 -#define F_CONF 33 -#define F_HALLU 34 - -#define NUM_STATS 35 - /* * Notes: * + Alignment needs a different init value, because -1 is an alignment. @@ -583,18 +1295,13 @@ long new_value; * [**] HD is shown instead of level and exp if Upolyd. */ static void -update_fancy_status(wp) -struct xwindow *wp; +update_fancy_status_field(i) +int i; { - struct X_status_value *sv; + struct X_status_value *sv = &shown_stats[i]; long val; - int i; - if (wp->cursy != 0) - return; /* do a complete update when line 0 is done */ - - for (i = 0, sv = shown_stats; i < NUM_STATS; i++, sv++) { - switch (i) { + switch (i) { case F_DUMMY: val = 0L; break; @@ -734,11 +1441,26 @@ struct xwindow *wp; val = 0L; break; } /* default */ - } /* switch */ - update_val(sv, val); - } + } /* switch */ + update_val(sv, val); } +static void +update_fancy_status(wp) +struct xwindow *wp; +{ + struct X_status_value *sv; + long val; + int i; + + /*if (wp->cursy != 0) + return;*/ /* do a complete update when line 0 is done */ + + for (i = 0; i < NUM_STATS; i++) + update_fancy_status_field(i); +} + + /* * Turn off hilighted status values after a certain amount of turns. */