Hilite Status: Improved

Allow defining multiple stops per field. Add hitpointbar.
This commit is contained in:
Pasi Kallinen
2017-09-26 10:04:25 +03:00
parent cac4344754
commit 69f7a78dba
37 changed files with 3227 additions and 1532 deletions
+1
View File
@@ -72,6 +72,7 @@ typedef struct mswin_nhmsg_update_status {
int n_fields;
const char **vals;
boolean *activefields;
int *percents;
int *colors;
} MSNHMsgUpdateStatus, *PMSNHMsgUpdateStatus;
+76 -35
View File
@@ -18,10 +18,10 @@ typedef struct mswin_nethack_status_window {
int n_fields;
const char **vals;
boolean *activefields;
int *percents;
int *colors;
} NHStatusWindow, *PNHStatusWindow;
#ifdef STATUS_VIA_WINDOWPORT
static int fieldorder1[] = { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN,
BL_WI, BL_CH, BL_ALIGN, BL_SCORE, -1 };
static int fieldorder2[] = { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX,
@@ -29,7 +29,6 @@ static int fieldorder2[] = { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX,
BL_EXP, BL_HD, BL_TIME, BL_HUNGER,
BL_CAP, BL_CONDITION, -1 };
static int *fieldorders[] = { fieldorder1, fieldorder2, NULL };
#endif /* STATUS_VIA_WINDOWPORT */
static TCHAR szStatusWindowClass[] = TEXT("MSNHStatusWndClass");
LRESULT CALLBACK StatusWndProc(HWND, UINT, WPARAM, LPARAM);
@@ -133,9 +132,10 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case MSNH_MSG_GETTEXT: {
PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam;
#ifdef STATUS_VIA_WINDOWPORT
#ifdef STATUS_HILITES
int **fop;
int *f;
msg_data->buffer[0] = '\0';
if (data->n_fields > 0) {
for (fop = fieldorders; *fop; fop++) {
@@ -143,20 +143,20 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (data->activefields[*f])
strncat(msg_data->buffer, data->vals[*f],
msg_data->max_size
- strlen(msg_data->buffer));
- strlen(msg_data->buffer));
}
strncat(msg_data->buffer, "\r\n",
msg_data->max_size - strlen(msg_data->buffer));
}
}
#else /* STATUS_VIA_WINDOWPORT */
#else
strncpy(msg_data->buffer, data->window_text[0],
msg_data->max_size);
strncat(msg_data->buffer, "\r\n",
msg_data->max_size - strlen(msg_data->buffer));
strncat(msg_data->buffer, data->window_text[1],
msg_data->max_size - strlen(msg_data->buffer));
#endif /* STATUS_VIA_WINDOWPORT */
#endif
} break;
case MSNH_MSG_UPDATE_STATUS: {
@@ -164,6 +164,7 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
data->n_fields = msg_data->n_fields;
data->vals = msg_data->vals;
data->activefields = msg_data->activefields;
data->percents = msg_data->percents;
data->colors = msg_data->colors;
InvalidateRect(hWnd, NULL, TRUE);
} break;
@@ -206,10 +207,12 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
}
#ifdef STATUS_VIA_WINDOWPORT
#ifdef STATUS_HILITES
static LRESULT
onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
int hpbar_percent = 100;
int hpbar_color = NO_COLOR;
int *f;
int **fop;
SIZE sz;
@@ -238,45 +241,83 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
: (COLORREF) GetSysColor(DEFAULT_COLOR_FG_STATUS);
OldFg = SetTextColor(hdc, Fg);
if (iflags.wc2_hitpointbar && BL_HP < data->n_fields
&& data->activefields[BL_HP]) {
hpbar_percent = data->percents[BL_HP];
hpbar_color = data->colors[BL_HP] & 0x00ff;
}
for (fop = fieldorders; *fop; fop++) {
LONG left = rt.left;
LONG cy = 0;
int vlen;
for (f = *fop; *f != -1; f++) {
int clr, atr;
int fntatr = ATR_NONE;
HGDIOBJ fnt;
COLORREF nFg, nBg;
if (((*f) >= data->n_fields) || (!data->activefields[*f]))
continue;
clr = data->colors[*f] & 0x00ff;
atr = (data->colors[*f] & 0xff00) >> 8;
vlen = strlen(data->vals[*f]);
NH_A2W(data->vals[*f], wbuf, SIZE(wbuf));
if (!iflags.use_status_hilites) {
SelectObject(hdc, normalFont);
SetBkColor(hdc, Bg);
SetTextColor(hdc, Fg);
} else if (data->colors[*f] == CLR_MAX
|| data->colors[*f] == BL_HILITE_NONE) {
SelectObject(hdc, normalFont);
SetBkColor(hdc, Bg);
SetTextColor(hdc, Fg);
} else if (data->colors[*f] > 0) {
SelectObject(hdc, normalFont);
SetBkColor(hdc, Bg);
SetTextColor(hdc, nhcolor_to_RGB(data->colors[*f]));
} else if (data->colors[*f] == BL_HILITE_INVERSE) {
SelectObject(hdc, normalFont);
SetBkColor(hdc, Fg);
SetTextColor(hdc, Bg);
} else if (data->colors[*f] == BL_HILITE_BOLD) {
SelectObject(hdc, boldFont);
SetBkColor(hdc, Bg);
SetTextColor(hdc, Fg);
} else {
SelectObject(hdc, normalFont);
SetBkColor(hdc, Bg);
SetTextColor(hdc, Fg);
}
if (atr & HL_BOLD)
fntatr = ATR_BOLD;
else if (atr & HL_INVERSE)
fntatr = ATR_INVERSE;
else if (atr & HL_ULINE)
fntatr = ATR_ULINE;
else if (atr & HL_BLINK)
fntatr = ATR_BLINK;
else if (atr & HL_DIM)
fntatr = ATR_DIM;
fnt = mswin_get_font(NHW_STATUS, fntatr, hdc, FALSE);
nFg = (clr >= 0 && clr < CLR_MAX) ? nhcolor_to_RGB(clr) : Fg;
nBg = Bg;
GetTextExtentPoint32(hdc, wbuf, vlen, &sz);
DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
if (*f == BL_TITLE && iflags.wc2_hitpointbar) {
HBRUSH back_brush = CreateSolidBrush(nhcolor_to_RGB(hpbar_color));
RECT barrect;
/* first draw title normally */
SelectObject(hdc, fnt);
SetBkMode(hdc, OPAQUE);
SetBkColor(hdc, Bg);
SetTextColor(hdc, nhcolor_to_RGB(hpbar_color));
DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
/* calc bar length */
barrect.left = rt.left;
barrect.top = rt.top;
barrect.bottom = sz.cy;
if (hpbar_percent > 0)
barrect.right = (int)((hpbar_percent * sz.cx) / 100);
else
barrect.right = sz.cx;
/* then draw hpbar on top of title */
FillRect(hdc, &barrect, back_brush);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, nBg);
DrawText(hdc, wbuf, vlen, &barrect, DT_LEFT);
DeleteObject(back_brush);
} else {
if (atr & HL_INVERSE) {
COLORREF tmp = nFg;
nFg = nBg;
nBg = tmp;
}
SelectObject(hdc, fnt);
SetBkMode(hdc, OPAQUE);
SetBkColor(hdc, nBg);
SetTextColor(hdc, nFg);
DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
}
rt.left += sz.cx;
cy = max(cy, sz.cy);
@@ -336,7 +377,7 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
return 0;
}
#endif /*STATUS_VIA_WINDOWPORT*/
#endif /* !STATUS_HILITES */
void
mswin_status_window_size(HWND hWnd, LPSIZE sz)
+16 -126
View File
@@ -85,6 +85,9 @@ struct window_procs mswin_procs = {
| WC_FONTSIZ_TEXT | WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_TILE_FILE
| WC_VARY_MSGCOUNT | WC_WINDOWCOLORS | WC_PLAYER_SELECTION
| WC_SPLASH_SCREEN | WC_POPUP_DIALOG | WC_MOUSE_SUPPORT,
#ifdef STATUS_HILITES
WC2_HITPOINTBAR | WC2_FLUSH_STATUS |
#endif
0L, mswin_init_nhwindows, mswin_player_selection, mswin_askname,
mswin_get_nh_event, mswin_exit_nhwindows, mswin_suspend_nhwindows,
mswin_resume_nhwindows, mswin_create_nhwindow, mswin_clear_nhwindow,
@@ -108,13 +111,8 @@ struct window_procs mswin_procs = {
/* other defs that really should go away (they're tty specific) */
mswin_start_screen, mswin_end_screen, mswin_outrip,
mswin_preference_update, mswin_getmsghistory, mswin_putmsghistory,
#ifdef STATUS_VIA_WINDOWPORT
mswin_status_init, mswin_status_finish, mswin_status_enablefield,
mswin_status_update,
#ifdef STATUS_HILITES
mswin_status_threshold,
#endif
#endif
genl_can_suspend_yes,
};
@@ -2713,18 +2711,18 @@ NHMessageBox(HWND hWnd, LPCTSTR text, UINT type)
return MessageBox(hWnd, text, title, type);
}
#ifdef STATUS_VIA_WINDOWPORT
static const char *_status_fieldnm[MAXBLSTATS];
static const char *_status_fieldfmt[MAXBLSTATS];
static char *_status_vals[MAXBLSTATS];
static int _status_colors[MAXBLSTATS];
static int _status_percents[MAXBLSTATS];
static boolean _status_activefields[MAXBLSTATS];
extern winid WIN_STATUS;
#ifdef STATUS_HILITES
typedef struct hilite_data_struct {
int thresholdtype;
anything threshold;
anything value;
int behavior;
int under;
int over;
@@ -2747,6 +2745,7 @@ mswin_status_init(void)
_status_activefields[i] = FALSE;
_status_fieldfmt[i] = (const char *) 0;
_status_colors[i] = CLR_MAX; /* no color */
_status_percents[i] = 0;
#ifdef STATUS_HILITES
_status_hilites[i].thresholdtype = 0;
_status_hilites[i].behavior = BL_TH_NONE;
@@ -2804,64 +2803,9 @@ mswin_status_enablefield(int fieldidx, const char *nm, const char *fmt,
_status_activefields[fieldidx] = enable;
}
#ifdef STATUS_HILITES
/*
status_threshold(int fldidx, int threshholdtype, anything threshold,
int behavior, int under, int over)
-- called when a hiliting preference is added, changed, or
removed.
-- the fldindex identifies which field is having its hiliting
preference set. It is an integer index value from botl.h
-- fldindex could be any one of the following from botl.h:
BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH,
BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX,
BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
BL_LEVELDESC, BL_EXP, BL_CONDITION
-- datatype is P_INT, P_UINT, P_LONG, or P_MASK.
-- threshold is an "anything" union which can contain the
datatype value.
-- behavior is used to define how threshold is used and can
be BL_TH_NONE, BL_TH_VAL_PERCENTAGE, BL_TH_VAL_ABSOLUTE,
or BL_TH_UPDOWN. BL_TH_NONE means don't do anything above
or below the threshold. BL_TH_VAL_PERCENTAGE treats the
threshold value as a precentage of the maximum possible
value. BL_TH_VAL_ABSOLUTE means that the threshold is an
actual value. BL_TH_UPDOWN means that threshold is not
used, and the two below/above hilite values indicate how
to display something going down (under) or rising (over).
-- under is the hilite attribute used if value is below the
threshold. The attribute can be BL_HILITE_NONE,
BL_HILITE_INVERSE, BL_HILITE_BOLD (-1, -2, or -3), or one
of the color indexes of CLR_BLACK, CLR_RED, CLR_GREEN,
CLR_BROWN, CLR_BLUE, CLR_MAGENTA, CLR_CYAN, CLR_GRAY,
CLR_ORANGE, CLR_BRIGHT_GREEN, CLR_YELLOW, CLR_BRIGHT_BLUE,
CLR_BRIGHT_MAGENTA, CLR_BRIGHT_CYAN, or CLR_WHITE (0 - 15).
-- over is the hilite attribute used if value is at or above
the threshold. The attribute can be BL_HILITE_NONE,
BL_HILITE_INVERSE, BL_HILITE_BOLD (-1, -2, or -3), or one
of the color indexes of CLR_BLACK, CLR_RED, CLR_GREEN,
CLR_BROWN, CLR_BLUE, CLR_MAGENTA, CLR_CYAN, CLR_GRAY,
CLR_ORANGE, CLR_BRIGHT_GREEN, CLR_YELLOW, CLR_BRIGHT_BLUE,
CLR_BRIGHT_MAGENTA, CLR_BRIGHT_CYAN, or CLR_WHITE (0 - 15).
*/
void
mswin_status_threshold(int fldidx, int thresholdtype, anything threshold,
int behavior, int under, int over)
{
logDebug("mswin_status_threshold(%d, %d, %d, %d, %d)\n", fldidx,
thresholdtype, behavior, under, over);
assert(fldidx >= 0 && fldidx < MAXBLSTATS);
_status_hilites[fldidx].thresholdtype = thresholdtype;
_status_hilites[fldidx].threshold = threshold;
_status_hilites[fldidx].behavior = behavior;
_status_hilites[fldidx].under = under;
_status_hilites[fldidx].over = over;
}
#endif /* STATUS_HILITES */
/*
status_update(int fldindex, genericptr_t ptr, int chg, int percentage)
status_update(int fldindex, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks)
-- update the value of a status field.
-- the fldindex identifies which field is changing and
is an integer index value from botl.h
@@ -2894,9 +2838,13 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percentage)
symbol for GOLD "\GXXXXNNNN:nnn". If window port needs
textual gold amount without the leading "$:" the port will
have to skip past ':' in passed "ptr" for the BL_GOLD case.
-- color is the color that the NetHack core is telling you to
use to display the text.
-- colormasks is a pointer to a set of CLR_MAX unsigned longs
telling you which fields should be displayed in each color.
*/
void
mswin_status_update(int idx, genericptr_t ptr, int chg, int percent)
mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks)
{
long cond, *condptr = (long *) ptr;
char *text = (char *) ptr;
@@ -2905,11 +2853,12 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent)
unsigned ospecial;
long value = -1;
logDebug("mswin_status_update(%d, %p, %d, %d)\n", idx, ptr, chg, percent);
logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, colormasks);
if (idx != BL_FLUSH) {
if (!_status_activefields[idx])
return;
_status_percents[idx] = percent;
switch (idx) {
case BL_CONDITION: {
cond = *condptr;
@@ -2971,75 +2920,16 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent)
}
}
#ifdef STATUS_HILITES
switch (_status_hilites[idx].behavior) {
case BL_TH_NONE: {
_status_colors[idx] = CLR_MAX;
} break;
case BL_TH_UPDOWN: {
if (chg > 0)
_status_colors[idx] = _status_hilites[idx].over;
else if (chg < 0)
_status_colors[idx] = _status_hilites[idx].under;
else
_status_colors[idx] = CLR_MAX;
} break;
case BL_TH_VAL_PERCENTAGE: {
int pct_th = 0;
if (_status_hilites[idx].thresholdtype != ANY_INT) {
impossible("mswin_status_update: unsupported percentage "
"threshold type %d",
_status_hilites[idx].thresholdtype);
break;
}
pct_th = _status_hilites[idx].threshold.a_int;
_status_colors[idx] = (percent >= pct_th)
? _status_hilites[idx].over
: _status_hilites[idx].under;
} break;
case BL_TH_VAL_ABSOLUTE: {
int c = CLR_MAX;
int o = _status_hilites[idx].over;
int u = _status_hilites[idx].under;
anything *t = &_status_hilites[idx].threshold;
switch (_status_hilites[idx].thresholdtype) {
case ANY_LONG:
c = (value >= t->a_long) ? o : u;
break;
case ANY_INT:
c = (value >= t->a_int) ? o : u;
break;
case ANY_UINT:
c = ((unsigned long) value >= t->a_uint) ? o : u;
break;
case ANY_ULONG:
c = ((unsigned long) value >= t->a_ulong) ? o : u;
break;
case ANY_MASK32:
c = (value & t->a_ulong) ? o : u;
break;
default:
impossible("mswin_status_update: unsupported absolute threshold "
"type %d\n",
_status_hilites[idx].thresholdtype);
break;
}
_status_colors[idx] = c;
} break;
}
#endif /* STATUS_HILITES */
_status_colors[idx] = color;
/* send command to status window */
ZeroMemory(&update_cmd_data, sizeof(update_cmd_data));
update_cmd_data.n_fields = MAXBLSTATS;
update_cmd_data.vals = _status_vals;
update_cmd_data.activefields = _status_activefields;
update_cmd_data.percents = _status_percents;
update_cmd_data.colors = _status_colors;
SendMessage(mswin_hwnd_from_winid(WIN_STATUS), WM_MSNH_COMMAND,
(WPARAM) MSNH_MSG_UPDATE_STATUS, (LPARAM) &update_cmd_data);
}
#endif /*STATUS_VIA_WINDOWPORT*/
+1 -8
View File
@@ -182,18 +182,11 @@ void mswin_preference_update(const char *pref);
char *mswin_getmsghistory(BOOLEAN_P init);
void mswin_putmsghistory(const char *msg, BOOLEAN_P);
#ifdef STATUS_VIA_WINDOWPORT
void mswin_status_init(void);
void mswin_status_finish(void);
void mswin_status_enablefield(int fieldidx, const char *nm, const char *fmt,
boolean enable);
void mswin_status_update(int idx, genericptr_t ptr, int chg, int percent);
#ifdef STATUS_HILITES
void mswin_status_threshold(int fldidx, int thresholdtype, anything threshold,
int behavior, int under, int over);
#endif /* STATUS_HILITES */
#endif /*STATUS_VIA_WINDOWPORT*/
void mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks);
/* helper function */
HWND mswin_hwnd_from_winid(winid wid);