#endif
#include <X11/Intrinsic.h>
-#include <X11/IntrinsicP.h>
+#include <X11/IntrinsicP.h> /* for XtResizeWidget() and XtConfigureWidget() */
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/AsciiText.h>
-#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Cardinals.h> /* just for ONE, TWO */
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Paned.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Viewport.h>
-#include <X11/Xatom.h>
+/*#include <X11/Xatom.h>*/
#ifdef PRESERVE_NO_SYSV
#ifdef SYSV
#define F_WIS 5
#define F_CHA 6
-#define F_NAME 7
-#define F_DLEVEL 8
+#define F_NAME 7 /* title: "Name the Rank" where rank is role-specific */
+#define F_DLEVEL 8 /* location: dungeon branch and level */
#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_XP_LEVL 15
+/*#define F_HD F_XP_LEVL*/
+#define F_EXP_PTS 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 *));
+/* status conditions grouped by columns; tty orders these differently;
+ hunger/encumbrance/movement used to be in the middle with fatal
+ conditions on the left but those columns have been swapped and
+ renumbered to match new order (forcing shown_stat[] to be reordered) */
+#define F_HUNGER 20
+#define F_ENCUMBER 21
+#define F_TRAPPED 22
+#define F_LEV 23
+#define F_FLY 24
+#define F_RIDE 25
+
+#define F_GRABBED 26
+#define F_STONE 27
+#define F_SLIME 28
+#define F_STRNGL 29
+#define F_FOODPOIS 30
+#define F_TERMILL 31
+#define F_IN_LAVA 32
+
+#define F_HELD 33
+#define F_BLIND 34
+#define F_DEAF 35
+#define F_STUN 36
+#define F_CONF 37
+#define F_HALLU 38
+
+#define NUM_STATS 39
+
+static int FDECL(condcolor, (long, unsigned long *));
+static int FDECL(condattr, (long, unsigned long *));
+static void FDECL(HiliteField, (Widget, int, int, int, XFontStruct **));
+static void FDECL(PrepStatusField, (int, Widget, const char *));
+static void FDECL(DisplayCond, (int, unsigned long *));
+static int FDECL(render_conditions, (int, int));
+#ifdef STATUS_HILITES
+static void FDECL(tt_reset_color, (int, int, unsigned long *));
+#endif
+static void NDECL(tt_status_fixup);
+static Widget FDECL(create_tty_status_field, (int, int, Widget, Widget));
+static Widget FDECL(create_tty_status, (Widget, Widget));
static void FDECL(update_fancy_status_field, (int));
+static void FDECL(update_fancy_status, (BOOLEAN_P));
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 *,
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 unsigned long X11_condition_bits, old_condition_bits;
+static int X11_status_colors[MAXBLSTATS],
+ old_field_colors[MAXBLSTATS],
+ old_cond_colors[32];
static int hpbar_percent, hpbar_color;
+/* Number of conditions displayed during this update and last update.
+ When the last update had more, the excess need to be erased. */
+static int next_cond_indx = 0, prev_cond_indx = 0;
+/* TODO: support statuslines:3 in addition to 2 for the tty-style status */
#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] = {
+static enum statusfields X11_fieldorder[][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_CAP, BL_CONDITION, BL_FLUSH }
};
+/* condition list for tty-style display, roughly in order of importance */
+static struct tt_condinfo {
+ unsigned long mask;
+ const char *text;
+} tt_condorder[] = {
+ { BL_MASK_GRAB, "Grab!" },
+ { BL_MASK_STONE, "Stone" },
+ { BL_MASK_SLIME, "Slime" },
+ { BL_MASK_STRNGL, "Strngl" },
+ { BL_MASK_FOODPOIS, "FoodPois" },
+ { BL_MASK_TERMILL, "TermIll" },
+ { BL_MASK_INLAVA, "Lava" },
+ { BL_MASK_HELD, "Held" },
+ { BL_MASK_BLIND, "Blind" },
+ { BL_MASK_DEAF, "Deaf" },
+ { BL_MASK_STUN, "Stun" },
+ { BL_MASK_CONF, "Conf" },
+ { BL_MASK_HALLU, "Hallu" },
+ { BL_MASK_TRAPPED, "Trap" },
+ { BL_MASK_LEV, "Lev" },
+ { BL_MASK_FLY, "Fly" },
+ { BL_MASK_RIDE, "Ride" },
+};
+
static Widget X11_status_widget;
static Widget X11_status_labels[MAXBLSTATS];
static Widget X11_cond_labels[32]; /* Ugh */
+static XFontStruct *X11_status_font;
+static Pixel X11_status_fg, X11_status_bg;
struct xwindow *xw_status_win;
-static Pixel X11_status_widget_fg, X11_status_widget_bg;
-
-int
+static int
condcolor(bm, bmarray)
long bm;
unsigned long *bmarray;
return NO_COLOR;
}
-int
+static int
condattr(bm, bmarray)
long bm;
unsigned long *bmarray;
void
X11_status_init()
{
-#ifdef STATUS_HILITES
int i;
+ /* no color and no attributes */
for (i = 0; i < MAXBLSTATS; ++i)
- X11_status_colors[i] = NO_COLOR; /* no color */
- X11_condition_bits = 0L;
+ X11_status_colors[i] = old_field_colors[i] = NO_COLOR;
+ for (i = 0; i < SIZE(old_cond_colors); ++i)
+ old_cond_colors[i] = NO_COLOR;
hpbar_percent = 0, hpbar_color = NO_COLOR;
-#endif /* STATUS_HILITES */
+ X11_condition_bits = old_condition_bits = 0L;
/* let genl_status_init do most of the initialization */
genl_status_init();
}
X11_status_finish()
{
/* nothing */
+ return;
}
void
genl_status_enablefield(fieldidx, nm, fmt, enable);
}
-
+#if 0
int
cond_bm2idx(bm)
unsigned long bm;
{
int i;
+
for (i = 0; i < 32; i++)
if ((1 << i) == bm)
return i;
return -1;
}
+#endif
-void
-MaybeDisplayCond(bm, colormasks, text)
-unsigned long bm;
-unsigned long *colormasks;
+/* highlight a tty-style status field (or condition) */
+static void
+HiliteField(label, fld, cond, colrattr, font_p)
+Widget label;
+int fld, cond, colrattr;
+XFontStruct **font_p;
+{
+#ifdef STATUS_HILITES
+ static Pixel grayPxl, blackPxl, whitePxl;
+ Arg args[6];
+ Cardinal num_args;
+ XFontStruct *font = X11_status_font;
+ Pixel px, fg = X11_status_fg, bg = X11_status_bg;
+ struct xwindow *xw = xw_status_win;
+ int colr, attr;
+
+#ifdef TEXTCOLOR
+ if ((colrattr & 0x00ff) >= CLR_MAX)
+ /* for !TEXTCOLOR, the following line is unconditional */
+#endif
+ colrattr = (colrattr & ~0x00ff) | NO_COLOR;
+ colr = colrattr & 0x00ff; /* guaranteed to be >= 0 and < CLR_MAX */
+ attr = (colrattr >> 8) & 0x00ff;
+
+ /* potentially used even for !TEXTCOLOR configuration */
+ if (!grayPxl) {/* one-time init */
+ grayPxl = get_nhcolor(xw, CLR_GRAY).pixel;
+ blackPxl = get_nhcolor(xw, CLR_BLACK).pixel;
+ whitePxl = get_nhcolor(xw, CLR_WHITE).pixel;
+ }
+ /* [shouldn't be necessary; setting up gray will set up all colors] */
+ if (colr != NO_COLOR && !xw->nh_colors[colr].pixel)
+ (void) get_nhcolor(xw, colr);
+
+ /* handle highlighting if caller has specified that; set foreground,
+ background, and font even if not specified this time in case they
+ used modified values last time (which would stick if not reset) */
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ if (colr != NO_COLOR)
+ fg = xw->nh_colors[colr].pixel;
+ if ((attr & HL_INVERSE) != 0) {
+ px = fg;
+ fg = bg;
+ bg = px;
+ }
+ /* foreground and background might both default to black, so we
+ need to force one to be different if/when they're the same
+ (actually, tt_status_fixup() takes care of that nowadays);
+ using gray to implement 'dim' only works for black and white
+ (or color+'inverse' when former background was black or white) */
+ if (fg == bg
+ || ((attr & HL_DIM) != 0 && (fg == whitePxl || fg == blackPxl)))
+ fg = (fg != grayPxl) ? grayPxl
+ : (fg != blackPxl) ? blackPxl
+ : whitePxl;
+ XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++;
+ if (attr & HL_BOLD) {
+ load_boldfont(xw_status_win, label);
+ if (xw_status_win->boldfs)
+ font = xw_status_win->boldfs;
+ }
+ XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++;
+ XtSetValues(label, args, num_args);
+
+ /* return possibly modified font to caller so that text width
+ measurement can use it */
+ if (font_p)
+ *font_p = font;
+#else /*!STATUS_HILITES*/
+ nhUse(label);
+ nhUse(font_p);
+#endif /*?STATUS_HILITES*/
+ if (fld != BL_CONDITION)
+ old_field_colors[fld] = colrattr;
+ else
+ old_cond_colors[cond] = colrattr;
+}
+
+/* set up a specific field other than 'condition'; its general location
+ was specified during widget creation but it might need adjusting */
+static void
+PrepStatusField(fld, label, text)
+int fld;
+Widget label;
const char *text;
{
- int idx = cond_bm2idx(bm);
+ Arg args[6];
+ Cardinal num_args;
+ Dimension lbl_wid;
+ XFontStruct *font = X11_status_font;
+ int colrattr = X11_status_colors[fld];
+ struct status_info_t *si = xw_status_win->Win_info.Status_info;
+
+ /* highlight if color and/or attribute(s) are different from last time */
+ if (colrattr != old_field_colors[fld])
+ HiliteField(label, fld, 0, colrattr, &font);
+
+ num_args = 0;
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ /* set up the current text to be displayed */
+ if (text && *text) {
+ lbl_wid = 2 * si->in_wd + XTextWidth(font, text, (int) strlen(text));
+ } else {
+ text = "";
+ lbl_wid = 1;
+ }
+ XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++;
+ /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/
+ XtSetValues(label, args, num_args);
+ XtResizeWidget(label, lbl_wid, si->ht, si->brd);
+}
+
+/* set up one status condition for tty-style status display */
+static void
+DisplayCond(c_idx, colormasks)
+int c_idx; /* index into tt_condorder[] */
+unsigned long *colormasks;
+{
Widget label;
- Arg args[10];
+ Arg args[6];
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;
+ XFontStruct *font = X11_status_font;
+ int coloridx, attrmask, colrattr, idx;
+ unsigned long bm = tt_condorder[c_idx].mask;
+ const char *text = tt_condorder[c_idx].text;
+ struct status_info_t *si = xw_status_win->Win_info.Status_info;
- if (idx < 0)
+ if ((X11_condition_bits & bm) == 0)
return;
+ /* widgets have been created for every condition; we allocate them
+ from left to right rather than keeping their original assignments */
+ idx = next_cond_indx;
label = X11_cond_labels[idx];
- if ((X11_condition_bits & bm) != 0) {
- int attrmask, coloridx;
- XFontStruct *font;
- Position lbl_x;
- Position lbl_y;
-#ifdef TEXTCOLOR
- coloridx = condcolor(bm, colormasks);
-#else
- coloridx = NO_COLOR;
-#endif
- attrmask = condattr(bm, colormasks);
+ /* handle highlighting if caller requests it */
+ coloridx = condcolor(bm, colormasks);
+ attrmask = condattr(bm, colormasks);
+ colrattr = (attrmask << 8) | coloridx;
+ if (colrattr != old_cond_colors[c_idx])
+ HiliteField(label, BL_CONDITION, c_idx, colrattr, &font);
+
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ /* set the condition text and its width; this widget might have
+ been displaying a different condition last time around */
+ XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++;
+ /* measure width after maybe changing font [HiliteField()] */
+ lbl_wid = 2 * si->in_wd + XTextWidth(font, text, (int) strlen(text));
+ /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/
+
+ /* make this condition widget be ready for display */
+ XtSetValues(label, args, num_args);
+ XtResizeWidget(label, lbl_wid, si->ht, si->brd);
+
+ ++next_cond_indx;
+}
+
+/* display the tty-style status conditions; the number shown varies and
+ we might be showing more, same, or fewer than during previous status */
+static int
+render_conditions(row, dx)
+int row, dx;
+{
+ Widget label;
+ Arg args[6];
+ Cardinal num_args;
+ Position lbl_x;
+ int i, gap = 5;
+ struct status_info_t *si = xw_status_win->Win_info.Status_info;
+ Dimension lbl_wid, brd_wid = si->brd;
+
+ for (i = 0; i < next_cond_indx; i++) {
+ label = X11_cond_labels[i];
+
+ /* width of this widget was set in DisplayCond(); fetch it */
+ (void) memset((genericptr_t) args, 0, sizeof args);
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;
+ /* figure out where to draw this widget and place it there */
+ lbl_x = (Position) (dx + 1 + gap);
- 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)
- ? get_nhcolor(xw_status_win, coloridx).pixel
- : X11_status_widget_fg;
- if (attrmask & HL_INVERSE) {
- Pixel tmppx = fg;
-
- fg = bg;
- bg = tmppx;
- }
+ XtConfigureWidget(label, lbl_x, si->y[row], lbl_wid, si->ht, brd_wid);
- if (attrmask & HL_BOLD) {
- load_boldfont(xw_status_win, label);
- XtSetArg(args[num_args], nhStr(XtNfont),
- xw_status_win->boldfs); num_args++;
+ /* keep track of where the end of our text appears */
+ dx = (int) lbl_x + (int) (lbl_wid + 2 * brd_wid) - 1;
+ }
+
+ /* if we have fewer conditions shown now than last time, set the
+ excess ones to blank; unlike the set drawn above, these haven't
+ been prepared in advance by DisplayCond because they aren't
+ being displayed; they might have been highlighted last time so
+ we need to specify more than just an empty text string */
+ if (next_cond_indx < prev_cond_indx) {
+ XFontStruct *font = X11_status_font;
+ Pixel fg = X11_status_fg, bg = X11_status_bg;
+
+ lbl_x = dx + 1;
+ lbl_wid = 1 + 2 * brd_wid;
+ for (i = next_cond_indx; i < prev_cond_indx; ++i) {
+ label = X11_cond_labels[i];
+
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++;
+ /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/
+ /*XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++;*/
+ XtSetValues(label, args, num_args);
+ old_cond_colors[i] = NO_COLOR; /* fg, bg, font were just reset */
+ XtConfigureWidget(label, lbl_x, si->y[row], lbl_wid, si->ht, 0);
+ /* don't advance 'dx' here */
}
+ }
- if (fg == bg)
- fg = get_nhcolor(xw_status_win, CLR_GRAY).pixel;
+ return dx;
+}
- 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);
+#ifdef STATUS_HILITES
+/* reset status_hilite for BL_RESET; if highlighting has been disabled or
+ this field is disabled, clear highlighting for this field or condition */
+static void
+tt_reset_color(fld, cond, colormasks)
+int fld, cond;
+unsigned long *colormasks;
+{
+ Widget label;
+ int colrattr = NO_COLOR;
- 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);
+ if (fld != BL_CONDITION) {
+ if (iflags.hilite_delta != 0L && status_activefields[fld])
+ colrattr = X11_status_colors[fld];
+ cond = 0;
+ label = X11_status_labels[fld];
+ } else {
+ unsigned long bm = tt_condorder[cond].mask;
- XtResizeWidget(label, lbl_wid, lbl_hei, lbl_border_wid);
+ if (iflags.hilite_delta != 0L && (X11_condition_bits & bm) != 0) {
+ /* BL_RESET before first BL_CONDITION will have colormasks==Null
+ but condcolor() and condattr() can cope with that */
+#ifdef TEXTCOLOR
+ colrattr = condcolor(bm, colormasks);
+#endif
+ colrattr |= (condattr(bm, colormasks) << 8);
+ }
+ label = X11_cond_labels[cond];
}
+ HiliteField(label, fld, cond, colrattr, (XFontStruct **) 0);
}
+#endif
+/* make sure foreground, background, and font have reasonable values,
+ then explicitly set them for all the status widgets;
+ also cache some geometry settings in (*xw_status_win).Status_info */
+static void
+tt_status_fixup()
+{
+ Arg args[6];
+ Cardinal num_args;
+ Widget w;
+ Position lbl_y;
+ int x, y, ci, fld;
+ XFontStruct *font = 0;
+ Pixel fg = 0, bg = 0;
+ struct status_info_t *si = xw_status_win->Win_info.Status_info;
-void
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[num_args], nhStr(XtNfont), &font); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNforeground), &fg); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNbackground), &bg); num_args++;
+ XtGetValues(X11_status_widget, args, num_args);
+ if (fg == bg) {
+ XColor black = get_nhcolor(xw_status_win, CLR_BLACK),
+ white = get_nhcolor(xw_status_win, CLR_WHITE);
+
+ fg = (bg == white.pixel) ? black.pixel : white.pixel;
+ }
+ X11_status_fg = si->fg = fg, X11_status_bg = si->bg = bg;
+
+ if (!font) {
+ w = X11_status_widget;
+ XtSetArg(args[0], nhStr(XtNfont), &font);
+ do {
+ XtGetValues(w, args, ONE);
+ } while (!font && (w = XtParent(w)) != 0);
+
+ if (!font) {
+ /* trial and error time -- this is where we've actually
+ been obtaining the font even though we aren't setting
+ it for any of the field widgets (until for(y,x) below) */
+ XtGetValues(X11_status_labels[0], args, ONE);
+
+ if (!font) { /* this bit is untested... */
+ /* write some text and hope Xaw sets up font for us */
+ XtSetArg(args[0], nhStr(XtNlabel), "NetHack");
+ XtSetValues(X11_status_labels[0], args, ONE);
+ (void) XFlush(XtDisplay(X11_status_labels[0]));
+
+ XtSetArg(args[0], nhStr(XtNfont), &font);
+ XtGetValues(X11_status_labels[0], args, ONE);
+
+ /* if still Null, XTextWidth() would crash so bail out */
+ if (!font)
+ panic("X11 status can't determine font.");
+ }
+ }
+ }
+ X11_status_font = si->fs = font;
+
+ /* amount of space to advance a widget's location by one space;
+ increase width a tiny bit beyond the actual space */
+ si->spacew = XTextWidth(X11_status_font, " ", 1) + (Dimension) 1;
+
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++;
+ XtSetValues(X11_status_widget, args, num_args);
+
+ for (y = 0; y < X11_NUM_STATUS_LINES; y++) {
+ for (x = 0; x < X11_NUM_STATUS_FIELD; x++) {
+ fld = X11_fieldorder[y][x]; /* next field to handle */
+ if (fld <= BL_FLUSH)
+ continue; /* skip fieldorder[][] padding */
+
+ XtSetValues(X11_status_labels[fld], args, num_args);
+ old_field_colors[fld] = NO_COLOR;
+
+ if (fld == BL_CONDITION) {
+ for (ci = 0; ci < SIZE(X11_cond_labels); ++ci) { /* 0..31 */
+ XtSetValues(X11_cond_labels[ci], args, num_args);
+ old_cond_colors[ci] = NO_COLOR;
+ }
+ }
+ }
+ }
+
+ /* cache the y coordinate of each row for XtConfigureWidget() */
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[0], nhStr(XtNy), &lbl_y); num_args++;
+ for (y = 0; y < X11_NUM_STATUS_LINES; y++) {
+ fld = X11_fieldorder[y][0];
+ XtGetValues(X11_status_labels[fld], args, num_args);
+ si->y[y] = lbl_y;
+ }
+
+ /* cache height, borderWidth, and internalWidth for XtResizeWidget() */
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[num_args], nhStr(XtNheight), &si->ht); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNborderWidth), &si->brd); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNinternalWidth), &si->in_wd); num_args++;
+ XtGetValues(X11_status_labels[0], args, num_args);
+}
+
+/* core requests updating one status field (or is indicating that it's time
+ to flush all updated fields); tty-style handling */
+static void
X11_status_update_tty(fld, ptr, chg, percent, color, colormasks)
int fld, chg UNUSED, percent, color;
genericptr_t ptr;
-unsigned long *colormasks;
+unsigned long *colormasks; /* bitmask of highlights for conditions */
{
- static boolean oncearound = FALSE; /* prevent premature partial display */
- long *condptr = (long *) ptr;
- int coloridx = NO_COLOR;
- const char *text = (char *) ptr;
- char tmpbuf[BUFSZ];
- int attridx = 0;
-
- XFontStruct *font;
- Arg args[10];
+ static int xtra_space[MAXBLSTATS];
+ static unsigned long *cond_colormasks = (unsigned long *) 0;
+
+ Arg args[6];
Cardinal num_args;
Position lbl_x;
- Position lbl_y;
- Dimension lbl_wid;
- Dimension lbl_hei;
- Dimension lbl_border_wid;
- Dimension lbl_iwidth;
+ Dimension lbl_wid, brd_wid;
Widget label;
- Pixel fg = X11_status_widget_fg, bg = X11_status_widget_bg;
-#ifndef TEXTCOLOR
- color = NO_COLOR;
-#endif
+ struct status_info_t *si;
+ char goldbuf[40];
+ const char *fmt;
+ const char *text;
+ unsigned long *condptr;
+ int f, x, y, dx;
- if (fld < BL_RESET || fld >= MAXBLSTATS)
- return;
+ if (X11_status_fg == X11_status_bg || !X11_status_font)
+ tt_status_fixup();
+
+ if (fld == BL_RESET) {
+#ifdef STATUS_HILITES
+ for (y = 0; y < X11_NUM_STATUS_LINES; y++) {
+ for (x = 0; x < X11_NUM_STATUS_FIELD; x++) {
+ f = X11_fieldorder[y][x];
+ if (f <= BL_FLUSH)
+ continue; /* skip padding in the fieldorder[][] layout */
+ if (f != BL_CONDITION) {
+ tt_reset_color(f, 0, (unsigned long *) 0);
+ } else {
+ int c_i;
+
+ for (c_i = 0; c_i < SIZE(tt_condorder); ++c_i)
+ tt_reset_color(f, c_i, cond_colormasks);
+ }
+ }
+ }
+#endif
+ fld = BL_FLUSH;
+ }
- if ((fld >= 0 && fld < MAXBLSTATS) && !status_activefields[fld])
+ if (fld == BL_CONDITION) {
+ condptr = (unsigned long *) ptr;
+ X11_condition_bits = *condptr;
+ cond_colormasks = colormasks; /* expected to be non-Null */
+
+ prev_cond_indx = next_cond_indx;
+ next_cond_indx = 0;
+ /* if any conditions are active, set up their widgets */
+ if (X11_condition_bits)
+ for (f = 0; f < SIZE(tt_condorder); ++f)
+ DisplayCond(f, cond_colormasks);
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);
- X11_status_colors[fld] = color;
- if (iflags.wc2_hitpointbar && fld == BL_HP) {
- hpbar_percent = percent;
- hpbar_color = color;
- }
- 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 if (fld != BL_FLUSH) {
+ /* set up a specific field other than 'condition' */
+ text = (char *) ptr;
+ if (fld == BL_GOLD)
+ text = decode_mixed(goldbuf, text);
+ xtra_space[fld] = 0;
+ if (status_activefields[fld]) {
+ fmt = (fld == BL_TITLE && iflags.wc2_hitpointbar) ? "%-30s"
+ : status_fieldfmt[fld] ? status_fieldfmt[fld] : "%s";
+ if (*fmt == ' ') {
+ ++xtra_space[fld];
+ ++fmt;
+ }
+ Sprintf(status_vals[fld], fmt, text);
} 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;
+ /* don't expect this since core won't call status_update()
+ for a field which isn't active */
+ *status_vals[fld] = '\0';
+ }
+#ifndef TEXTCOLOR
+ /* even without color, attribute(s) bits still apply */
+ color = (color & ~0x00ff) | NO_COLOR;
#endif
- attridx = (X11_status_colors[fld] & 0xFF00) >> 8;
+#ifdef STATUS_HILITES
+ if (!iflags.hilite_delta)
+ color = NO_COLOR;
+#endif
+ X11_status_colors[fld] = color;
+ if (iflags.wc2_hitpointbar && fld == BL_HP) {
+ hpbar_percent = percent;
+ hpbar_color = color;
+ }
- 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);
+ label = X11_status_labels[fld];
+ text = status_vals[fld];
+ PrepStatusField(fld, label, text);
+ return;
+ }
- /*raw_printf("font: %i-%i",
- font->min_bounds.width, font->max_bounds.width);*/
+ /*
+ * BL_FLUSH: draw all the status fields.
+ */
+ si = xw_status_win->Win_info.Status_info; /* for cached geometry */
- if (text && *text)
- lbl_wid = lbl_iwidth + font->max_bounds.width * strlen(text);
- else
- lbl_wid = 1;
+ for (y = 0; y < X11_NUM_STATUS_LINES; y++) { /* row */
+ dx = 0; /* no pixels written to this row yet */
- /*raw_printf("1:lbl_wid=%i('%s')", lbl_wid, text);*/
+ for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { /* 'column' */
+ f = X11_fieldorder[y][x];
+ if (f <= BL_FLUSH)
+ continue; /* skip padding in the fieldorder[][] layout */
- 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)
- ? get_nhcolor(xw_status_win, coloridx).pixel
- : X11_status_widget_fg;
- if (attridx & HL_INVERSE) {
- Pixel tmppx = fg;
-
- fg = bg;
- bg = tmppx;
+ if (f == BL_CONDITION) {
+ if (next_cond_indx > 0 || prev_cond_indx > 0)
+ dx = render_conditions(y, dx);
+ continue;
}
- if (attridx & HL_BOLD) {
- load_boldfont(xw_status_win, label);
- XtSetArg(args[num_args], nhStr(XtNfont),
- xw_status_win->boldfs); num_args++;
- }
+ label = X11_status_labels[f];
+ text = status_vals[f];
- if (fg == bg)
- fg = get_nhcolor(xw_status_win, CLR_GRAY).pixel;
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++;
+ XtGetValues(label, args, num_args);
+ brd_wid = si->brd;
- 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 a field which shouldn't be shown, we can't just skip
+ it because we might need to remove its previous content
+ if it has just been toggled off */
+ if (!status_activefields[f]) {
+ if (lbl_wid <= 1)
+ continue;
+ text = "";
+ lbl_wid = (Dimension) 1;
+ brd_wid = (Dimension) 0;
+ } else if (xtra_space[f]) {
+ /* if this field was to be formatted with a leading space
+ to separate it from the preceding field, we suppressed
+ that space during formatting; insert separation between
+ fields here; this prevents inverse video highlighting
+ from inverting the separating space along with the text */
+ dx += xtra_space[f] * si->spacew;
+ }
- for (y = 0; y < X11_NUM_STATUS_LINES; y++) {
- Cardinal dx = 0;
+ /* where to display the current widget */
+ lbl_x = (Position) (dx + 1);
- for (x = 0; x < X11_NUM_STATUS_FIELD; x++) {
- int f = X11_fieldorder[y][x];
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++;
+ /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/
+ /*XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++;*/
+ XtSetValues(label, args, num_args);
+ XtConfigureWidget(label, lbl_x, si->y[y],
+ lbl_wid, si->ht, brd_wid);
- if (f <= BL_FLUSH)
- continue;
- if (!status_activefields[f])
- continue;
+ /* track the right-most pixel written so far */
+ dx = (int) lbl_x + (int) (lbl_wid + 2 * brd_wid) - 1;
+ } /* [x] fields/columns in current row */
+ } /* [y] rows */
- 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;
- }
- }
- }
+ /* this probably doesn't buy us anything but it isn't a sure thing
+ that nethack will immediately ask for input (triggering auto-flush) */
+ (void) XFlush(XtDisplay(X11_status_labels[0]));
}
/*ARGSUSED*/
-void
+static void
X11_status_update_fancy(fld, ptr, chg, percent, color, colormasks)
int fld, chg UNUSED, percent UNUSED, color UNUSED;
genericptr_t ptr;
unsigned long *colormasks UNUSED;
{
- static const struct {
+ static const struct bl_to_ff {
int bl, ff;
} bl_to_fancyfield[] = {
{ BL_TITLE, F_NAME },
{ BL_GOLD, F_GOLD },
{ BL_ENE, F_POWER },
{ BL_ENEMAX, F_MAXPOWER },
- { BL_XP, F_LEVEL },
+ { BL_XP, F_XP_LEVL }, /* shares with BL_HD, depending upon Upolyd */
{ 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 }
+ { BL_EXP, F_EXP_PTS }
};
- static const struct {
+ static const struct mask_to_ff {
unsigned long mask;
int ff;
} mask_to_fancyfield[] = {
+ { BL_MASK_GRAB, F_GRABBED },
{ 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_INLAVA, F_IN_LAVA },
+ { BL_MASK_HELD, F_HELD },
{ 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_TRAPPED, F_TRAPPED },
{ 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);
+ update_fancy_status(FALSE);
}
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);
+ unsigned long changed_bits, *condptr = (unsigned long *) ptr;
+
+ X11_condition_bits = *condptr;
+ /* process the bits that are different from last time */
+ changed_bits = (X11_condition_bits ^ old_condition_bits);
+ if (changed_bits) {
+ for (i = 0; i < SIZE(mask_to_fancyfield); i++)
+ if ((changed_bits & mask_to_fancyfield[i].mask) != 0L)
+ update_fancy_status_field(mask_to_fancyfield[i].ff);
+ old_condition_bits = X11_condition_bits;
+ }
} else {
for (i = 0; i < SIZE(bl_to_fancyfield); i++)
- if (bl_to_fancyfield[i].bl == fld)
+ if (bl_to_fancyfield[i].bl == fld) {
update_fancy_status_field(bl_to_fancyfield[i].ff);
+ break;
+ }
}
}
genericptr_t ptr;
unsigned long *colormasks;
{
+ if (fld < BL_RESET || fld >= MAXBLSTATS)
+ panic("X11_status_update(%d) -- invalid field", fld);
+
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);
}
-Widget
+/* create a widget for a particular status field or potential condition */
+static Widget
+create_tty_status_field(fld, condindx, above, left)
+int fld, condindx;
+Widget above, left;
+{
+ Arg args[16];
+ Cardinal num_args;
+ char labelname[40];
+ int gap = condindx ? 5 : 0;
+
+ if (!condindx)
+ Sprintf(labelname, "label_%s", bl_idx_to_fldname(fld));
+ else
+ Sprintf(labelname, "cond_%02d", condindx);
+
+ /* set up widget attributes which (mostly) aren't going to be changing */
+ (void) memset((genericptr_t) args, 0, sizeof args);
+ num_args = 0;
+ if (above)
+ XtSetArg(args[num_args], nhStr(XtNfromVert), above); num_args++;
+ if (left)
+ XtSetArg(args[num_args], nhStr(XtNfromHoriz), left); num_args++;
+
+ XtSetArg(args[num_args], nhStr(XtNhorizDistance), gap); 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++;
+ /* internalWidth: default is 4; cut that it half and adjust regular
+ width to have it on both left and right instead of just on the left */
+ XtSetArg(args[num_args], nhStr(XtNinternalWidth), 2); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++;
+ return XtCreateManagedWidget(labelname, labelWidgetClass,
+ X11_status_widget, args, num_args);
+}
+
+/* create an overall status widget (X11_status_widget) and also
+ separate widgets for all status fields and potential conditions */
+static Widget
create_tty_status(parent, top)
Widget parent, top;
{
- Widget form; /* The form that surrounds everything. */
- Widget w;
- Arg args[16];
+ Widget form; /* viewport that holds the form that surrounds everything */
+ Widget w, over_w, prev_w;
+ Arg args[6];
Cardinal num_args;
- int i, x, y;
+ int x, y, i, fld;
+ (void) memset((genericptr_t) args, 0, sizeof args);
num_args = 0;
- if (top != (Widget) 0) {
+ if (top)
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++;
form = XtCreateManagedWidget("status_viewport", viewportWidgetClass,
parent, args, num_args);
+ (void) memset((genericptr_t) args, 0, sizeof 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);
+ X11_status_widget = XtCreateManagedWidget("status_form", formWidgetClass,
+ form, args, num_args);
+
for (y = 0; y < X11_NUM_STATUS_LINES; y++) {
+ fld = (y > 0) ? X11_fieldorder[y - 1][0] : 0; /* temp, for over_w */
+ /* for row(s) beyond the first, pick a widget in the previous
+ row to put this one underneath (in 'y' terms; 'x' is fluid) */
+ over_w = (y > 0) ? X11_status_labels[fld] : (Widget) 0;
+ /* widget on current row to put the next one to the right of ('x') */
+ prev_w = (Widget) 0;
for (x = 0; x < X11_NUM_STATUS_FIELD; x++) {
- int fld = X11_fieldorder[y][x];
- char labelname[BUFSZ];
- int prevfld;
-
+ fld = X11_fieldorder[y][x]; /* next field to handle */
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++;
- }
+ continue; /* skip fieldorder[][] padding */
- XtSetArg(args[num_args], nhStr(XtNhorizDistance), 0); num_args++;
- XtSetArg(args[num_args], nhStr(XtNvertDistance), 0); num_args++;
+ w = create_tty_status_field(fld, 0, over_w, prev_w);
+ X11_status_labels[fld] = prev_w = w;
- 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);
+ if (fld == BL_CONDITION) {
+ for (i = 1; i <= SIZE(X11_cond_labels); ++i) { /* 1..32 */
+ w = create_tty_status_field(fld, i, over_w, prev_w);
+ X11_cond_labels[i - 1] = prev_w = w;
+ }
+ }
}
- }
-
- 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);
}
-
- return w;
+ return X11_status_widget;
}
/*ARGSUSED*/
boolean create_popup UNUSED;
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);
+ wp->w = create_tty_status(parent, (Widget) 0);
}
void
const char *str UNUSED;
{
/* nothing */
+ return;
}
void
boolean create_popup;
Widget parent;
{
+ struct status_info_t *si = (struct status_info_t *) alloc(sizeof *si);
+
xw_status_win = wp;
- if (appResources.fancy_status)
- create_status_window_fancy(wp, create_popup, parent);
- else
+ if (wp->Win_info.Status_info)
+ free((genericptr_t) wp->Win_info.Status_info);
+ wp->Win_info.Status_info = si;
+ (void) memset((genericptr_t) si, 0, sizeof *si);
+
+ if (!appResources.fancy_status)
create_status_window_tty(wp, create_popup, parent);
+ else
+ create_status_window_fancy(wp, create_popup, parent);
}
void
adjust_status_tty(wp, str);
}
-extern const char *hu_stat[]; /* from eat.c */
-extern const char *enc_stat[]; /* from botl.c */
-
void
create_status_window_fancy(wp, create_popup, parent)
struct xwindow *wp; /* window pointer */
XtSetArg(args[num_args], nhStr(XtNbottomMargin),
&bottom_margin); num_args++;
XtSetArg(args[num_args], nhStr(XtNleftMargin), &left_margin); num_args++;
- XtSetArg(args[num_args], nhStr(XtNrightMargin), &right_margin); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNrightMargin),
+ &right_margin); num_args++;
XtGetValues(wp->w, args, num_args);
wp->pixel_height = 2 * nhFontHeight(wp->w) + top_margin + bottom_margin;
Cardinal num_args;
if (!wp->status_information) {
- update_fancy_status(wp);
+ update_fancy_status(TRUE);
return;
}
XtSetValues(wp->w, args, num_args);
}
-/* Fancy Status
- * -------------------------------------------------------------*/
+/* Fancy ================================================================== */
static int hilight_time = 1; /* number of turns to hilight a changed value */
struct X_status_value {
/* valid type values */
#define SV_VALUE 0 /* displays a label:value pair */
#define SV_LABEL 1 /* displays a changable label */
-#define SV_NAME 2 /* displays an unchangeable name */
+#define SV_NAME 2 /* displays an unchangeable name */
static void FDECL(hilight_label, (Widget));
static void FDECL(update_val, (struct X_status_value *, long));
static void FDECL(get_widths, (struct X_status_value *, int *, int *));
static void FDECL(set_widths, (struct X_status_value *, int, int));
static Widget FDECL(init_column, (const char *, Widget, Widget, Widget,
- int *));
+ int *, int));
static void NDECL(fixup_cond_widths);
static Widget FDECL(init_info_form, (Widget, Widget, Widget));
* + Alignment needs a different init value, because -1 is an alignment.
* + Armor Class is an schar, so 256 is out of range.
* + Blank value is 0 and should never change.
+ *
+ * - These must be in the same order as the F_foo numbers.
*/
static struct X_status_value shown_stats[NUM_STATS] = {
- { "", SV_NAME, (Widget) 0, -1, 0, FALSE, FALSE }, /* 0*/
+ { "", SV_NAME, (Widget) 0, -1, 0, FALSE, FALSE }, /* 0, F_DUMMY */
- { "Strength", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
+ { "Strength", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /* 1*/
{ "Dexterity", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Constitution", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Intelligence", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Wisdom", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /* 5*/
{ "Charisma", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "", SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* name */
- { "", SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* dlvl */
+ { "", SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* 7, F_NAME */
+ { "", SV_LABEL, (Widget) 0, -1, 0, FALSE, FALSE }, /* F_DLEVEL */
{ "Gold", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Hit Points", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /*10*/
{ "Max HP", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Power", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Max Power", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Armor Class", SV_VALUE, (Widget) 0, 256, 0, FALSE, FALSE },
- { "Level", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /*15*/
- { "Experience", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
+ { "Xp Level", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE }, /*15*/
+ /*{ "Hit Dice", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },==15*/
+ { "Exp Points", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Alignment", SV_VALUE, (Widget) 0, -2, 0, FALSE, FALSE },
{ "Time", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
{ "Score", SV_VALUE, (Widget) 0, -1, 0, FALSE, FALSE },
- { "Petrifying", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*20*/
+ { "", SV_NAME, (Widget) 0, -1, 0, FALSE, TRUE }, /*20, F_HUNGER */
+ { "", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /* F_ENCUMBER */
+ { "Trapped", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Levitating", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Flying", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Riding", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*25, F_RIDE */
+
+ { "Grabbed!", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*26, F_GRAB */
+ { "Petrifying", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /* F_STONE */
{ "Slimed", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
{ "Strangled", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "Food Pois", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Food Pois", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*30*/
{ "Term Ill", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Sinking", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /* 32, F_IN_LAVA */
- { "", SV_NAME, (Widget) 0, -1, 0, FALSE, TRUE }, /*25*/ /* hunger */
- { "", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*encumbr */
- { "Levitating", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "Flying", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "Riding", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
-
- { "Blind", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*30*/
- { "Deaf", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Held", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*33*/
+ { "Blind", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Deaf", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*35*/
{ "Stunned", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
{ "Confused", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
- { "Hallucinating", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE },
+ { "Hallucinating", SV_NAME, (Widget) 0, 0, 0, FALSE, TRUE }, /*38*/
};
+extern const char *hu_stat[]; /* from eat.c */
+extern const char *enc_stat[]; /* from botl.c */
+
/*
* Set all widget values to a null string. This is used after all spacings
* have been calculated so that when the window is popped up we don't get all
}
}
-/* This is almost an exact duplicate of hilight_value() */
+/* this is almost an exact duplicate of hilight_value() */
static void
hilight_label(w)
Widget w; /* label widget */
{
Arg args[2];
Pixel fg, bg;
+ /*
+ * This predates STATUS_HILITES.
+ * It is used to show any changed item in inverse and gets
+ * reset on the next turn.
+ */
XtSetArg(args[0], XtNforeground, &fg);
XtSetArg(args[1], XtNbackground, &bg);
struct X_status_value *attr_rec;
long new_value;
{
+ static boolean Exp_shown = TRUE, time_shown = TRUE, score_shown = TRUE,
+ Xp_was_HD = FALSE;
char buf[BUFSZ];
Arg args[4];
attr_rec->last_value = new_value;
- /* special cases: hunger, encumbrance, sickness */
+ /* special cases: hunger and encumbrance */
if (attr_rec == &shown_stats[F_HUNGER]) {
XtSetArg(args[0], XtNlabel, hu_stat[new_value]);
} else if (attr_rec == &shown_stats[F_ENCUMBER]) {
/* special case: time can be enabled & disabled */
if (attr_rec == &shown_stats[F_TIME]) {
- static boolean flagtime = TRUE;
-
- if (flags.time && !flagtime) {
+ if (flags.time && !time_shown) {
set_name(attr_rec->w, shown_stats[F_TIME].name);
force_update = TRUE;
- flagtime = flags.time;
- } else if (!flags.time && flagtime) {
+ time_shown = TRUE;
+ } else if (!flags.time && time_shown) {
set_name(attr_rec->w, "");
set_value(attr_rec->w, "");
- flagtime = flags.time;
+ time_shown = FALSE;
}
- if (!flagtime)
+ if (!time_shown)
return;
- /* special case: exp can be enabled & disabled */
- } else if (attr_rec == &shown_stats[F_EXP]) {
- static boolean flagexp = TRUE;
+ /* special case: experience points can be enabled & disabled */
+ } else if (attr_rec == &shown_stats[F_EXP_PTS]) {
+ boolean showexp = flags.showexp && !Upolyd;
- if (flags.showexp && !flagexp) {
- set_name(attr_rec->w, shown_stats[F_EXP].name);
+ if (showexp && !Exp_shown) {
+ set_name(attr_rec->w, shown_stats[F_EXP_PTS].name);
force_update = TRUE;
- flagexp = flags.showexp;
- } else if (!flags.showexp && flagexp) {
+ Exp_shown = TRUE;
+ } else if (!showexp && Exp_shown) {
set_name(attr_rec->w, "");
set_value(attr_rec->w, "");
- flagexp = flags.showexp;
+ Exp_shown = FALSE;
}
- if (!flagexp)
+ if (!Exp_shown)
return;
- }
- /* special case: score can be enabled & disabled */
- else if (attr_rec == &shown_stats[F_SCORE]) {
- static boolean flagscore = TRUE;
+ /* special case: when available, score can be enabled & disabled */
+ } else if (attr_rec == &shown_stats[F_SCORE]) {
#ifdef SCORE_ON_BOTL
-
- if (flags.showscore && !flagscore) {
+ if (flags.showscore && !score_shown) {
set_name(attr_rec->w, shown_stats[F_SCORE].name);
force_update = TRUE;
- flagscore = flags.showscore;
- } else if (!flags.showscore && flagscore) {
+ score_shown = TRUE;
+ } else
+#endif
+ if (!flags.showscore && score_shown) {
set_name(attr_rec->w, "");
set_value(attr_rec->w, "");
- flagscore = flags.showscore;
+ score_shown = FALSE;
}
- if (!flagscore)
+ if (!score_shown)
return;
-#else
- if (flagscore) {
- set_name(attr_rec->w, "");
- set_value(attr_rec->w, "");
- flagscore = FALSE;
- }
- return;
-#endif
- /* special case: when polymorphed, show "HD", disable exp */
- } else if (attr_rec == &shown_stats[F_LEVEL]) {
- static boolean lev_was_poly = FALSE;
-
- if (Upolyd && !lev_was_poly) {
- force_update = TRUE;
- set_name(attr_rec->w, "HD");
- lev_was_poly = TRUE;
- } else if (Upolyd && lev_was_poly) {
- force_update = TRUE;
- set_name(attr_rec->w, shown_stats[F_LEVEL].name);
- lev_was_poly = FALSE;
- }
- } else if (attr_rec == &shown_stats[F_EXP]) {
- static boolean exp_was_poly = FALSE;
-
- if (Upolyd && !exp_was_poly) {
+ /* special case: when polymorphed, show "Hit Dice" and disable Exp */
+ } else if (attr_rec == &shown_stats[F_XP_LEVL]) {
+ if (Upolyd && !Xp_was_HD) {
force_update = TRUE;
- set_name(attr_rec->w, "");
- set_value(attr_rec->w, "");
- exp_was_poly = TRUE;
- } else if (Upolyd && exp_was_poly) {
+ set_name(attr_rec->w, "Hit Dice");
+ Xp_was_HD = TRUE;
+ } else if (!Upolyd && Xp_was_HD) {
force_update = TRUE;
- set_name(attr_rec->w, shown_stats[F_EXP].name);
- exp_was_poly = FALSE;
+ set_name(attr_rec->w, shown_stats[F_XP_LEVL].name);
+ Xp_was_HD = FALSE;
}
- if (Upolyd)
- return; /* no display for exp when poly */
+ /* core won't call status_update() for Exp when it hasn't changed
+ so do so ourselves (to get Exp_shown flag to match display) */
+ if (force_update)
+ update_fancy_status_field(F_EXP_PTS);
}
if (attr_rec->last_value == new_value && !force_update) /* same */
attr_rec->last_value = new_value;
- /* Special cases: strength, alignment and "clear". */
- if (attr_rec == &shown_stats[F_STR]) {
- if (new_value > 18) {
- if (new_value > 118)
- Sprintf(buf, "%ld", new_value - 100);
- else if (new_value < 118)
- Sprintf(buf, "18/%02ld", new_value - 18);
+ /* Special cases: strength and other characteristics, alignment
+ and "clear". */
+ if (attr_rec >= &shown_stats[F_STR]
+ && attr_rec <= &shown_stats[F_CHA]) {
+ static const char fmt1[] = "%ld%s", fmt2[] = "%2ld%s";
+ struct xwindow *wp;
+ const char *fmt = fmt1, *padding = "";
+
+ /* for full-fledged fancy status, force two digits for all
+ six characteristics, followed by three spaces of padding
+ to match "/xx" exceptional strength */
+ wp = (WIN_STATUS != WIN_ERR) ? &window_list[WIN_STATUS] : 0;
+ if (wp && !wp->status_information)
+ fmt = fmt2, padding = " ";
+
+ if (new_value > 18L && attr_rec == &shown_stats[F_STR]) {
+ if (new_value > 118L) /* 19..25 encoded as 119..125 */
+ Sprintf(buf, fmt, new_value - 100L, padding);
+ else if (new_value < 118L) /* 18/01..18/99 as 19..117*/
+ Sprintf(buf, "18/%02ld", new_value - 18L);
else
- Strcpy(buf, "18/**");
- } else {
- Sprintf(buf, "%ld", new_value);
+ Strcpy(buf, "18/**"); /* 18/100 encoded as 118 */
+ } else { /* non-strength or less than 18/01 strength (3..18) */
+ Sprintf(buf, fmt, new_value, padding); /* 3..25 */
}
} else if (attr_rec == &shown_stats[F_ALIGN]) {
- Strcpy(buf,
- (new_value == A_CHAOTIC)
- ? "Chaotic"
- : (new_value == A_NEUTRAL) ? "Neutral" : "Lawful");
+ Strcpy(buf, (new_value == A_CHAOTIC) ? "Chaotic"
+ : (new_value == A_NEUTRAL) ? "Neutral" : "Lawful");
} else {
Sprintf(buf, "%ld", new_value);
}
* the other. So only do our update when we update the second line.
*
* Information on the first line:
- * name, attributes, alignment, score
+ * name, characteristics, alignment, score
*
* Information on the second line:
* dlvl, gold, hp, power, ac, {level & exp or HD **}, time,
int i;
{
struct X_status_value *sv = &shown_stats[i];
- long val;
+ unsigned long condmask = 0L;
+ long val = 0L;
switch (i) {
case F_DUMMY:
val = (long) ACURR(A_CHA);
break;
/*
- * Label stats. With the exceptions of hunger, encumbrance, sick
+ * Label stats. With the exceptions of hunger and encumbrance
* these are either on or off. Pleae leave the ternary operators
* the way they are. I want to specify 0 or 1, not a boolean.
*/
case F_ENCUMBER:
val = (long) near_capacity();
break;
+
+ case F_TRAPPED:
+ condmask = BL_MASK_TRAPPED;
+ break;
case F_LEV:
- val = Levitation ? 1L : 0L;
+ condmask = BL_MASK_LEV;
break;
case F_FLY:
- val = Flying ? 1L : 0L;
+ condmask = BL_MASK_FLY;
break;
case F_RIDE:
- val = u.usteed ? 1L : 0L;
+ condmask = BL_MASK_RIDE;
break;
/* fatal status conditions */
+ case F_GRABBED:
+ condmask = BL_MASK_GRAB;
+ break;
case F_STONE:
- val = Stoned ? 1L : 0L;
+ condmask = BL_MASK_STONE;
break;
case F_SLIME:
- val = Slimed ? 1L : 0L;
+ condmask = BL_MASK_SLIME;
break;
case F_STRNGL:
- val = Strangled ? 1L : 0L;
+ condmask = BL_MASK_STRNGL;
break;
case F_FOODPOIS:
- val = (Sick && (u.usick_type & SICK_VOMITABLE)) ? 1L : 0L;
+ condmask = BL_MASK_FOODPOIS;
break;
case F_TERMILL:
- val = (Sick && (u.usick_type & SICK_NONVOMITABLE)) ? 1L : 0L;
+ condmask = BL_MASK_TERMILL;
+ break;
+ case F_IN_LAVA:
+ condmask = BL_MASK_INLAVA;
break;
/* non-fatal status conditions */
+ case F_HELD:
+ condmask = BL_MASK_HELD;
+ break;
case F_BLIND:
- val = Blind ? 1L : 0L;
+ condmask = BL_MASK_BLIND;
break;
case F_DEAF:
- val = Deaf ? 1L : 0L;
+ condmask = BL_MASK_DEAF;
break;
case F_STUN:
- val = Stunned ? 1L : 0L;
+ condmask = BL_MASK_STUN;
break;
case F_CONF:
- val = Confusion ? 1L : 0L;
+ condmask = BL_MASK_CONF;
break;
case F_HALLU:
- val = Hallucination ? 1L : 0L;
+ condmask = BL_MASK_HALLU;
break;
case F_NAME:
- val = (long) 0L;
- break; /* special */
case F_DLEVEL:
val = (long) 0L;
break; /* special */
+
case F_GOLD:
val = money_cnt(g.invent);
if (val < 0L)
case F_AC:
val = (long) u.uac;
break;
- case F_LEVEL:
+ case F_XP_LEVL:
val = (long) (Upolyd ? mons[u.umonnum].mlevel : u.ulevel);
break;
- case F_EXP:
+ case F_EXP_PTS:
val = flags.showexp ? u.uexp : 0L;
break;
case F_ALIGN:
break;
} /* default */
} /* switch */
+
+ if (condmask)
+ val = ((X11_condition_bits & condmask) != 0L);
update_val(sv, val);
}
-/*ARGUSED*/
+/* fully update status after bl_flush or window resize */
static void
-update_fancy_status(wp)
-struct xwindow *wp UNUSED;
+update_fancy_status(force_update)
+boolean force_update;
{
+ static boolean old_showtime, old_showexp, old_showscore;
+ static int old_upolyd = -1; /* -1: force first time update */
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);
+ if (force_update
+ || Upolyd != old_upolyd /* Xp vs HD */
+ || flags.time != old_showtime
+ || flags.showexp != old_showexp
+ || flags.showscore != old_showscore) {
+ /* update everything; usually only need this on the very first
+ time, then later if the window gets resized or if poly/unpoly
+ triggers Xp <-> HD switch or if an optional field gets
+ toggled off since there won't be a status_update() call for
+ the no longer displayed field; we're a bit more conservative
+ than that and do this when toggling on as well as off */
+ for (i = 0; i < NUM_STATS; i++)
+ update_fancy_status_field(i);
+
+ old_upolyd = Upolyd;
+ old_showtime = flags.time;
+ old_showexp = flags.showexp;
+ old_showscore = flags.showscore;
+ }
}
-
/*
* Turn off hilighted status values after a certain amount of turns.
*/
continue;
if (sv->turn_count++ >= hilight_time) {
+ /* unhighlights by toggling a highlit item back off again */
if (sv->type == SV_LABEL)
hilight_label(sv->w);
else
}
}
-/* Initialize alternate status =============================================
- */
+/* Initialize alternate status ============================================ */
-/* Return a string for the initial width. */
+/* Return a string for the initial width, so use longest possible value. */
static const char *
width_string(sv_index)
int sv_index;
case F_LEV:
case F_FLY:
case F_RIDE:
+ case F_TRAPPED:
+ case F_GRABBED:
case F_STONE:
case F_SLIME:
case F_STRNGL:
case F_FOODPOIS:
case F_TERMILL:
+ case F_IN_LAVA:
+ case F_HELD:
case F_BLIND:
case F_DEAF:
case F_STUN:
case F_NAME:
case F_DLEVEL:
- return "";
+ return ""; /* longest possible value not needed for these */
+
case F_HP:
case F_MAXHP:
return "9999";
return "9999";
case F_AC:
return "-127";
- case F_LEVEL:
+ case F_XP_LEVL:
return "99";
case F_GOLD:
/* strongest hero can pick up roughly 30% of this much */
return "999999"; /* same limit as tty */
- case F_EXP:
+ case F_EXP_PTS:
case F_TIME:
case F_SCORE:
return "123456789"; /* a tenth digit will still fit legibly */
}
static Widget
-init_column(name, parent, top, left, col_indices)
+init_column(name, parent, top, left, col_indices, xtrawidth)
const char *name;
Widget parent, top, left;
-int *col_indices;
+int *col_indices, xtrawidth;
{
Widget form;
Arg args[4];
if (left != (Widget) 0) {
XtSetArg(args[num_args], nhStr(XtNfromHoriz), left); num_args++;
}
- XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 0); num_args++;
+ /* this was 0 but that resulted in the text being crammed together */
+ XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 2); num_args++;
form = XtCreateManagedWidget(name, formWidgetClass, parent,
args, num_args);
if (width2 > max_width2)
max_width2 = width2;
}
+
+ /* insert some extra spacing between columns */
+ max_width1 += xtrawidth;
+
for (ip = col_indices; *ip >= 0; ip++) {
set_widths(&shown_stats[*ip], max_width1, max_width2);
}
* These are the orders of the displayed columns. Change to suit. The -1
* indicates the end of the column. The two numbers after that are used
* to store widths that are calculated at run-time.
+ *
+ * 3.7: changed so that all 6 columns have 8 rows, but a few entries
+ * are left blank <>. Exp-points, Score, and Time are optional depending
+ * on run-time settings; Xp-level is replaced by Hit-Dice (and Exp-points
+ * suppressed) when the hero is polymorphed. Title and Dungeon-Level span
+ * two columns and might expand to more if 'hitpointbar' is implemented.
+ *
+ Title ("Plname the Rank") <> <> <> <>
+ Dungeon-Branch-and-Level <> Hunger Grabbed Held
+ Hit-points Max-HP Strength Encumbrance Petrifying Blind
+ Power-points Max-Power Dexterity Trapped Slimed Deaf
+ Armor-class Alignment Constitution Levitation Strangled Stunned
+ Xp-level [Exp-points] Intelligence Flying Food-Pois Confused
+ Gold [Score] Wisdom Riding Term-Ill Hallucinatg
+ <> [Time] Charisma <> Sinking <>
+ *
+ * A seventh column is going to be needed to fit in more conditions.
+ *
+ * Possible enhancement: if Exp-points and Score are both disabled, move
+ * Gold to the Exp-points slot.
*/
-static int attrib_indices[] = { F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA,
- -1, 0, 0 };
+
/* including F_DUMMY makes the three status condition columns evenly
spaced with regard to the adjacent characteristics (Str,Dex,&c) column;
- we lose track of the Widget pointer for them, each use clobbering the
+ we lose track of the Widget pointer for F_DUMMY, each use clobbering the
one before, leaving the one from leftover_indices[]; since they're never
updated, that shouldn't matter */
-static int status_indices[3][9] = { { F_STONE, F_SLIME, F_STRNGL,
- F_FOODPOIS, F_TERMILL, F_DUMMY,
- -1, 0, 0 },
- { F_HUNGER, F_ENCUMBER,
- F_LEV, F_FLY, F_RIDE, F_DUMMY,
- -1, 0, 0 },
- { F_BLIND, F_DEAF, F_STUN,
- F_CONF, F_HALLU, F_DUMMY,
- -1, 0, 0 } };
+static int status_indices[3][11] = {
+ { F_DUMMY, F_HUNGER, F_ENCUMBER, F_TRAPPED,
+ F_LEV, F_FLY, F_RIDE, F_DUMMY, -1, 0, 0 },
+ { F_DUMMY, F_GRABBED, F_STONE, F_SLIME, F_STRNGL,
+ F_FOODPOIS, F_TERMILL, F_IN_LAVA, -1, 0, 0 },
+ { F_DUMMY, F_HELD, F_BLIND, F_DEAF, F_STUN,
+ F_CONF, F_HALLU, F_DUMMY, -1, 0, 0 },
+};
/* used to fill up the empty space to right of 3rd status condition column */
static int leftover_indices[] = { F_DUMMY, -1, 0, 0 };
+/* -2: top two rows of these columns are reserved for title and location */
+static int col1_indices[11 - 2] = {
+ F_HP, F_POWER, F_AC, F_XP_LEVL, F_GOLD, F_DUMMY, -1, 0, 0
+};
+static int col2_indices[11 - 2] = {
+ F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP_PTS, F_SCORE, F_TIME, -1, 0, 0
+};
+static int characteristics_indices[11 - 2] = {
+ F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA, -1, 0, 0
+};
-static int col1_indices[] = { F_HP, F_POWER, F_AC, F_LEVEL, F_GOLD,
- F_SCORE, -1, 0, 0 };
-static int col2_indices[] = { F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP, F_TIME,
- -1, 0, 0 };
/*
* Produce a form that looks like the following:
*
- * name
- * dlevel
- * col1_indices[0] col2_indices[0]
- * col1_indices[1] col2_indices[1]
- * . .
- * . .
- * col1_indices[n] col2_indices[n]
+ * title
+ * location
+ * col1_indices[0] col2_indices[0] col3_indices[0]
+ * col1_indices[1] col2_indices[1] col3_indices[1]
+ * ... ... ...
+ * col1_indices[5] col2_indices[5] col3_indices[5]
*
- * TODO: increase the space between the two columns.
+ * The status conditions are managed separately and appear to the right
+ * of this form.
+ *
+ * TODO: widen title field and implement hitpoint bar on it.
*/
static Widget
init_info_form(parent, top, left)
Widget parent, top, left;
{
- Widget form, col1;
+ Widget form, col1, col2;
struct X_status_value *sv_name, *sv_dlevel;
Arg args[6];
Cardinal num_args;
if (left != (Widget) 0) {
XtSetArg(args[num_args], nhStr(XtNfromHoriz), left); num_args++;
}
- XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 0); num_args++;
+ XtSetArg(args[num_args], nhStr(XtNdefaultDistance), 2); num_args++;
form = XtCreateManagedWidget("status_info", formWidgetClass, parent,
args, num_args);
- /* top of form */
- sv_name = &shown_stats[F_NAME];
+ /* top line/row of form */
+ sv_name = &shown_stats[F_NAME]; /* title */
create_widget(form, sv_name, F_NAME);
- /* second */
- sv_dlevel = &shown_stats[F_DLEVEL];
+ /* second line/row */
+ sv_dlevel = &shown_stats[F_DLEVEL]; /* location */
create_widget(form, sv_dlevel, F_DLEVEL);
num_args = 0;
XtSetArg(args[num_args], nhStr(XtNfromVert), sv_name->w); num_args++;
XtSetValues(sv_dlevel->w, args, num_args);
- /* two columns beneath */
+ /* there are 3 columns beneath but top 2 rows are centered over first 2 */
col1 = init_column("name_col1", form, sv_dlevel->w, (Widget) 0,
- col1_indices);
- (void) init_column("name_col2", form, sv_dlevel->w, col1, col2_indices);
+ col1_indices, 0);
+ col2 = init_column("name_col2", form, sv_dlevel->w, col1,
+ col2_indices, 5);
+ (void) init_column("status_characteristics", form, sv_dlevel->w, col2,
+ characteristics_indices, 15);
/* Add calculated widths. */
for (ip = col1_indices; *ip >= 0; ip++)
}
/* ascetics: expand the maximum width to make cond columns wider */
if (pass == 1) {
- w1 += 20;
+ w1 += 15;
if (w2 > 0)
- w2 += 20;
+ w2 += 15;
}
}
}
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], nhStr(XtNdefaultDistance), 2); num_args++;
XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
XtSetArg(args[num_args], XtNorientation, XtorientHorizontal); num_args++;
form = XtCreateManagedWidget("fancy_status", panedWidgetClass, parent,
args, num_args);
w = init_info_form(form, (Widget) 0, (Widget) 0);
- w = init_column("status_attributes", form, (Widget) 0, w, attrib_indices);
+#if 0 /* moved to init_info_form() */
+ w = init_column("status_characteristics", form, (Widget) 0, w,
+ characteristics_indices, 15);
+#endif
for (i = 0; i < 3; i++) {
Sprintf(buf, "status_condition%d", i + 1);
- w = init_column(buf, form, (Widget) 0, w, status_indices[i]);
+ w = init_column(buf, form, (Widget) 0, w, status_indices[i], 0);
}
fixup_cond_widths(); /* make all 3 status_conditionN columns same width */
- w = init_column("status_leftover", form, (Widget) 0, w, leftover_indices);
+ w = init_column("status_leftover", form, (Widget) 0, w,
+ leftover_indices, 0);
nhUse(w);
return form;
}