From ff12c334afc86a78d0513c1017a641b3ed5be582 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 10:15:43 -0800 Subject: [PATCH 1/4] Removed unnecessary use of static for nocreate values. If multiple games are played without exiting the process, on the second new player creation the nocreate values will already be set based on the first player creation. --- src/u_init.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/u_init.c b/src/u_init.c index 5b5c5113f..71da5a84a 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -974,15 +974,16 @@ register struct trobj *trop; struct obj *obj; int otyp, i; - while (trop->trclass) { + NEARDATA short nocreate = STRANGE_OBJECT; + NEARDATA short nocreate2 = STRANGE_OBJECT; + NEARDATA short nocreate3 = STRANGE_OBJECT; + NEARDATA short nocreate4 = STRANGE_OBJECT; + + while (trop->trclass) { otyp = (int) trop->trotyp; if (otyp != UNDEF_TYP) { obj = mksobj(otyp, TRUE, FALSE); } else { /* UNDEF_TYP */ - static NEARDATA short nocreate = STRANGE_OBJECT; - static NEARDATA short nocreate2 = STRANGE_OBJECT; - static NEARDATA short nocreate3 = STRANGE_OBJECT; - static NEARDATA short nocreate4 = STRANGE_OBJECT; /* * For random objects, do not create certain overly powerful * items: wand of wishing, ring of levitation, or the From 96eae720cee493dde5858769f767ea447f370468 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 22 Nov 2018 12:15:13 -0800 Subject: [PATCH 2/4] Revert "Removed unnecessary use of static for nocreate values." This reverts commit ff12c334afc86a78d0513c1017a641b3ed5be582. --- src/u_init.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/u_init.c b/src/u_init.c index 71da5a84a..5b5c5113f 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -974,16 +974,15 @@ register struct trobj *trop; struct obj *obj; int otyp, i; - NEARDATA short nocreate = STRANGE_OBJECT; - NEARDATA short nocreate2 = STRANGE_OBJECT; - NEARDATA short nocreate3 = STRANGE_OBJECT; - NEARDATA short nocreate4 = STRANGE_OBJECT; - - while (trop->trclass) { + while (trop->trclass) { otyp = (int) trop->trotyp; if (otyp != UNDEF_TYP) { obj = mksobj(otyp, TRUE, FALSE); } else { /* UNDEF_TYP */ + static NEARDATA short nocreate = STRANGE_OBJECT; + static NEARDATA short nocreate2 = STRANGE_OBJECT; + static NEARDATA short nocreate3 = STRANGE_OBJECT; + static NEARDATA short nocreate4 = STRANGE_OBJECT; /* * For random objects, do not create certain overly powerful * items: wand of wishing, ring of levitation, or the From 95e701cd01649170531bd07c1d9e51fd46f507d3 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 25 Nov 2018 20:31:50 -0800 Subject: [PATCH 3/4] Fix map clearing when in tile mode and tile is set to NO_GLYPH. --- win/win32/mhmap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 8e61aea8c..49c2a4e4e 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -746,6 +746,12 @@ paintTile(PNHMapWindow data, int i, int j, RECT * rect) glyph = data->map[i][j]; bkglyph = data->bkmap[i][j]; + if (glyph == NO_GLYPH && bkglyph == NO_GLYPH) { + HBRUSH blackBrush = CreateSolidBrush(RGB(0, 0, 0)); + FillRect(data->backBufferDC, rect, blackBrush); + DeleteObject(blackBrush); + } + if (bkglyph != NO_GLYPH) { ntile = glyph2tile[bkglyph]; t_x = TILEBMP_X(ntile); From c44c0d3e01765039caf858322f4aa0a479e38dc1 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 25 Nov 2018 21:04:30 -0800 Subject: [PATCH 4/4] Added support for color condition hilites to tile mode. Code is complete but might take another pass over the code to simplify where we can. --- include/botl.h | 6 +- win/win32/mhmsg.h | 6 +- win/win32/mhstatus.c | 105 +++++++++---------- win/win32/mhstatus.h | 69 +++++++++++++ win/win32/mswproc.c | 233 +++++++++++++++++++++++++++++-------------- 5 files changed, 283 insertions(+), 136 deletions(-) diff --git a/include/botl.h b/include/botl.h index 9e4e36595..f7cbce08f 100644 --- a/include/botl.h +++ b/include/botl.h @@ -35,14 +35,15 @@ enum statusfields { BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, /* 1..6 */ BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, /* 7..12 */ BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, /* 13..18 */ - BL_HPMAX, BL_LEVELDESC, BL_EXP, BL_CONDITION /* 19..22 */ + BL_HPMAX, BL_LEVELDESC, BL_EXP, BL_CONDITION, /* 19..22 */ + BL_COUNT }; enum relationships { NO_LTEQGT = -1, EQ_VALUE, LT_VALUE, LE_VALUE, GE_VALUE, GT_VALUE, TXT_VALUE }; -#define MAXBLSTATS (BL_CONDITION + 1) +#define MAXBLSTATS (BL_COUNT) #define BEFORE 0 #define NOW 1 @@ -63,6 +64,7 @@ enum relationships { NO_LTEQGT = -1, #define BL_MASK_LEV 0x00000400L #define BL_MASK_FLY 0x00000800L #define BL_MASK_RIDE 0x00001000L +#define BL_MASK_BITS 13 /* number of mask bits that can be set */ /* clang-format on */ #define REASSESS_ONLY TRUE diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 090068d82..7eb65d0c0 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -69,11 +69,7 @@ typedef struct mswin_nhmsg_get_text { } MSNHMsgGetText, *PMSNHMsgGetText; typedef struct mswin_nhmsg_update_status { - int n_fields; - const char **vals; - boolean *activefields; - int *percents; - int *colors; + struct mswin_status_lines * status_lines; } MSNHMsgUpdateStatus, *PMSNHMsgUpdateStatus; #endif diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index 074762816..57c70b436 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -9,7 +9,6 @@ #include "mhmsg.h" #include "mhfont.h" -#define NHSW_LINES 2 #define MAXWINDOWTEXT BUFSZ extern COLORREF nhcolor_to_RGB(int c); /* from mhmap */ @@ -60,24 +59,14 @@ void back_buffer_init(back_buffer_t * back_buffer, HWND hWnd, int width, int hei back_buffer_size(back_buffer, width, height); } + typedef struct mswin_nethack_status_window { int index; char window_text[NHSW_LINES][MAXWINDOWTEXT + 1]; - int n_fields; - const char **vals; - boolean *activefields; - int *percents; - int *colors; + mswin_status_lines * status_lines; back_buffer_t back_buffer; } NHStatusWindow, *PNHStatusWindow; -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, - BL_ENE, BL_ENEMAX, BL_AC, BL_XP, - BL_EXP, BL_HD, BL_TIME, BL_HUNGER, - BL_CAP, BL_CONDITION, -1 }; -static int *fieldorders[] = { fieldorder1, fieldorder2, NULL }; static TCHAR szStatusWindowClass[] = TEXT("MSNHStatusWndClass"); LRESULT CALLBACK StatusWndProc(HWND, UINT, WPARAM, LPARAM); @@ -195,22 +184,19 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case MSNH_MSG_GETTEXT: { PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam; #ifdef STATUS_HILITES - int **fop; - int *f; - msg_data->buffer[0] = '\0'; - if (data->n_fields > 0) { - for (fop = fieldorders; *fop; fop++) { - for (f = *fop; *f != -1; f++) { - if (data->activefields[*f]) - strncat(msg_data->buffer, data->vals[*f], - msg_data->max_size - - strlen(msg_data->buffer)); - } - strncat(msg_data->buffer, "\r\n", - msg_data->max_size - strlen(msg_data->buffer)); + + for (int line = 0; line < NHSW_LINES; line++) { + mswin_status_line *status_line = data->status_lines[line].lines; + for (int i = 0; i < status_line->status_strings.count; i++) { + mswin_status_string * status_string = status_line->status_strings.status_strings[i]; + strncat(msg_data->buffer, status_string->str, + msg_data->max_size - strlen(msg_data->buffer)); } + strncat(msg_data->buffer, "\r\n", + msg_data->max_size - strlen(msg_data->buffer)); } + #else strncpy(msg_data->buffer, data->window_text[0], msg_data->max_size); @@ -223,11 +209,7 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case MSNH_MSG_UPDATE_STATUS: { PMSNHMsgUpdateStatus msg_data = (PMSNHMsgUpdateStatus) 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; + data->status_lines = msg_data->status_lines; InvalidateRect(hWnd, NULL, TRUE); } break; } /* end switch( wParam ) { */ @@ -273,10 +255,6 @@ StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) static LRESULT onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) { - int hpbar_percent = 100; - int hpbar_color = NO_COLOR; - int *f; - int **fop; SIZE sz; HGDIOBJ normalFont, boldFont; WCHAR wbuf[BUFSZ]; @@ -308,12 +286,6 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) SetBkColor(hdc, status_bg_color); SetTextColor(hdc, status_fg_color); - 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; - } - clear_rect.left = 0; clear_rect.top = 0; clear_rect.right = width; @@ -321,23 +293,38 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) FillRect(hdc, &clear_rect, status_bg_brush); - for (fop = fieldorders; *fop; fop++) { + // TODO: Put it around for loop instead -- temporary to get a better diff + if (data->status_lines == NULL) { + BitBlt(front_buffer_hdc, 0, 0, width, height, hdc, 0, 0, SRCCOPY); + + EndPaint(hWnd, &ps); + return 0; + } + + for (int line = 0; line < NHSW_LINES; line++) { LONG left = rt.left; LONG cy = 0; int vlen; - for (f = *fop; *f != BL_FLUSH; f++) { + + mswin_status_line * status_line = &data->status_lines->lines[line]; + + for (int i = 0; i < status_line->status_strings.count; i++) { + mswin_status_string * status_string = status_line->status_strings.status_strings[i]; int clr, atr; int fntatr = ATR_NONE; HGDIOBJ fnt; COLORREF nFg, nBg; - if (((*f) >= data->n_fields) || (!data->activefields[*f])) + if (status_string->str == NULL || status_string->str[0] == '\0') continue; - clr = data->colors[*f] & 0x00ff; - atr = (data->colors[*f] & 0xff00) >> 8; - vlen = strlen(data->vals[*f]); - const char *str = data->vals[*f]; + + clr = status_string->color & 0x00ff; + atr = (status_string->color & 0xff00) >> 8; + + const char *str = status_string->str; + + vlen = strlen(str); if (atr & HL_BOLD) fntatr = ATR_BOLD; @@ -362,8 +349,13 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) nBg = status_bg_color; sz.cy = -1; - if (*f == BL_TITLE && iflags.wc2_hitpointbar) { - HBRUSH back_brush = CreateSolidBrush(nhcolor_to_RGB(hpbar_color)); + + if (status_string->draw_bar && iflags.wc2_hitpointbar) { + + /* when we are drawing bar we need to look at the hp status + * field to get the correct percentage and color */ + COLORREF bar_color = nhcolor_to_RGB(status_string->bar_color); + HBRUSH back_brush = CreateSolidBrush(bar_color); RECT barrect; /* prepare for drawing */ @@ -371,7 +363,7 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) SetBkMode(hdc, OPAQUE); SetBkColor(hdc, status_bg_color); /* SetTextColor(hdc, nhcolor_to_RGB(hpbar_color)); */ - SetTextColor(hdc, status_fg_color); + SetTextColor(hdc, status_fg_color); if (useUnicode) { /* get bounding rectangle */ @@ -379,21 +371,22 @@ onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam) /* first draw title normally */ DrawTextW(hdc, wbuf, vlen, &rt, DT_LEFT); - } else { + } + else { /* get bounding rectangle */ GetTextExtentPoint32A(hdc, str, vlen, &sz); /* first draw title normally */ DrawTextA(hdc, str, vlen, &rt, DT_LEFT); } - - if (hpbar_percent > 0) { + int bar_percent = status_string->bar_percent; + if (bar_percent > 0) { /* 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); + if (bar_percent > 0) + barrect.right = (int)((bar_percent * sz.cx) / 100); /* else barrect.right = sz.cx; */ diff --git a/win/win32/mhstatus.h b/win/win32/mhstatus.h index 2349a29f3..1f0d75d26 100644 --- a/win/win32/mhstatus.h +++ b/win/win32/mhstatus.h @@ -9,6 +9,75 @@ #include "config.h" #include "global.h" +#define NHSW_LINES 2 + +static const int fieldorder1[] = { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, + BL_WI, BL_CH, BL_ALIGN, BL_SCORE, -1 }; +static const int fieldorder2[] = { 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, -1 }; +static const int *fieldorders[] = { fieldorder1, fieldorder2, NULL }; +static const int fieldcounts[NHSW_LINES] = { SIZE(fieldorder1) - 1, SIZE(fieldorder2) - 1}; + +#define MSWIN_MAX_LINE1_STRINGS (SIZE(fieldorder1) - 1) +#define MSWIN_MAX_LINE2_STRINGS (SIZE(fieldorder2) - 1 + BL_MASK_BITS) +#define MSWIN_MAX_LINE_STRINGS (MSWIN_MAX_LINE1_STRINGS > MSWIN_MAX_LINE2_STRINGS ? \ + MSWIN_MAX_LINE1_STRINGS : MSWIN_MAX_LINE2_STRINGS) + +#define MSWIN_LINE1_FIELDS (SIZE(fieldorder1) - 1) +#define MSWIN_LINE2_FIELDS (SIZE(fieldorder2) - 1) +#define MSWIN_MAX_LINE_FIELDS (MSWIN_LINE1_FIELDS > MSWIN_LINE2_FIELDS ? \ + MSWIN_LINE1_FIELDS : MSWIN_LINE2_FIELDS) + +/* when status hilites are enabled, we use an array of mswin_status_strings + * to represent what needs to be rendered. */ +typedef struct mswin_status_string { + const char * str; /* ascii string to be displayed */ + int color; /* string text color */ + boolean draw_bar; + int bar_percent; /* a percentage to indicate; 100 will draw no percentage bar */ + int bar_color; /* color index of percentage bar */ +} mswin_status_string; + +typedef struct mswin_status_strings +{ + int count; + mswin_status_string * status_strings[MSWIN_MAX_LINE_STRINGS]; +} mswin_status_strings; + +typedef struct mswin_status_field { + int field_index; // field index + boolean enabled; // whether the field is enabled + const char * name; // name of status field + const char * format; // format of field + + int percent; + int color; + char string[BUFSZ]; + +} mswin_status_field; + +typedef struct mswin_condition_field { + int mask; + const char * name; + int bit_position; +} mswin_condition_field; + +typedef struct mswin_status_fields { + int count; + mswin_status_field * status_fields[MSWIN_MAX_LINE_FIELDS]; +} mswin_status_fields; + +typedef struct mswin_status_line { + mswin_status_strings status_strings; + mswin_status_fields status_fields; +} mswin_status_line; + +typedef struct mswin_status_lines { + mswin_status_line lines[NHSW_LINES]; /* number of strings to be rendered on each line */ +} mswin_status_lines; + HWND mswin_init_status_window(void); void mswin_status_window_size(HWND hWnd, LPSIZE sz); diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index c6714bc15..74a4cd3c6 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -2766,12 +2766,28 @@ NHMessageBox(HWND hWnd, LPCTSTR text, UINT type) return MessageBox(hWnd, text, title, type); } -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]; +static mswin_status_lines _status_lines; +static mswin_status_string _status_strings[MAXBLSTATS]; +static mswin_status_string _condition_strings[BL_MASK_BITS]; +static mswin_status_field _status_fields[MAXBLSTATS]; + +static mswin_condition_field _condition_fields[BL_MASK_BITS] = { + { BL_MASK_STONE, " Stone" }, + { BL_MASK_SLIME, " Slime" }, + { BL_MASK_STRNGL, " Strngl" }, + { BL_MASK_FOODPOIS, " FoodPois" }, + { BL_MASK_TERMILL, " TermIll" }, + { BL_MASK_BLIND, " Blind" }, + { BL_MASK_DEAF, " Deaf" }, + { BL_MASK_STUN, " Stun" }, + { BL_MASK_CONF, " Conf" }, + { BL_MASK_HALLU, " Hallu" }, + { BL_MASK_LEV, " Lev" }, + { BL_MASK_FLY, " Fly" }, + { BL_MASK_RIDE, " Ride" } +}; + + extern winid WIN_STATUS; #ifdef STATUS_HILITES @@ -2792,15 +2808,62 @@ status_init() -- core calls this to notify the window port that a status void mswin_status_init(void) { - int i; logDebug("mswin_status_init()\n"); - for (i = 0; i < MAXBLSTATS; ++i) { - _status_vals[i] = (char *) alloc(BUFSZ); - *_status_vals[i] = '\0'; - _status_activefields[i] = FALSE; - _status_fieldfmt[i] = (const char *) 0; - _status_colors[i] = CLR_MAX; /* no color */ - _status_percents[i] = 0; + + for (int i = 0; i < SIZE(_status_fields); i++) { + mswin_status_field * status_field = &_status_fields[i]; + status_field->field_index = i; + status_field->enabled = FALSE; + } + + for (int i = 0; i < SIZE(_condition_fields); i++) { + mswin_condition_field * condition_field = &_condition_fields[i]; + nhassert(condition_field->mask == (1 << i)); + condition_field->bit_position = i; + } + + for (int i = 0; i < SIZE(_status_strings); i++) { + mswin_status_string * status_string = &_status_strings[i]; + status_string->str = NULL; + } + + for (int i = 0; i < SIZE(_condition_strings); i++) { + mswin_status_string * status_string = &_condition_strings[i]; + status_string->str = NULL; + } + + for (int lineIndex = 0; lineIndex < SIZE(_status_lines.lines); lineIndex++) { + mswin_status_line * line = &_status_lines.lines[lineIndex]; + + mswin_status_fields * status_fields = &line->status_fields; + status_fields->count = 0; + + mswin_status_strings * status_strings = &line->status_strings; + status_strings->count = 0; + + for (int i = 0; i < fieldcounts[lineIndex]; i++) { + int field_index = fieldorders[lineIndex][i]; + nhassert(field_index <= SIZE(_status_fields)); + + nhassert(status_fields->count <= SIZE(status_fields->status_fields)); + status_fields->status_fields[status_fields->count++] = &_status_fields[field_index]; + + nhassert(status_strings->count <= SIZE(status_strings->status_strings)); + status_strings->status_strings[status_strings->count++] = + &_status_strings[field_index]; + + if (field_index == BL_CONDITION) { + for (int j = 0; j < BL_MASK_BITS; j++) { + nhassert(status_strings->count <= SIZE(status_strings->status_strings)); + status_strings->status_strings[status_strings->count++] = + &_condition_strings[j]; + } + } + } + } + + + for (int i = 0; i < MAXBLSTATS; ++i) { #ifdef STATUS_HILITES _status_hilites[i].thresholdtype = 0; _status_hilites[i].behavior = BL_TH_NONE; @@ -2820,17 +2883,7 @@ status_finish() -- called when it is time for the window port to tear down void mswin_status_finish(void) { - /* tear down routine */ - int i; - logDebug("mswin_status_finish()\n"); - - /* free alloc'd memory here */ - for (i = 0; i < MAXBLSTATS; ++i) { - if (_status_vals[i]) - free((genericptr_t) _status_vals[i]); - _status_vals[i] = (char *) 0; - } } /* @@ -2853,9 +2906,41 @@ mswin_status_enablefield(int fieldidx, const char *nm, const char *fmt, { logDebug("mswin_status_enablefield(%d, %s, %s, %d)\n", fieldidx, nm, fmt, (int) enable); - _status_fieldfmt[fieldidx] = fmt; - _status_fieldnm[fieldidx] = nm; - _status_activefields[fieldidx] = enable; + + nhassert(fieldidx <= SIZE(_status_fields)); + mswin_status_field * field = &_status_fields[fieldidx]; + + nhassert(fieldidx <= SIZE(_status_strings)); + mswin_status_string * string = &_status_strings[fieldidx]; + + if (field != NULL) { + field->format = fmt; + field->name = nm; + field->enabled = enable; + + string->str = (field->enabled ? field->string : NULL); + + if (field->field_index == BL_CONDITION) + string->str = NULL; + + string->draw_bar = (field->enabled && field->field_index == BL_TITLE); + } +} + +/* TODO: turn this into a commmon helper; multiple identical implementations */ +static int +mswin_condcolor(bm, bmarray) +long bm; +unsigned long *bmarray; +{ + int i; + + if (bm && bmarray) + for (i = 0; i < CLR_MAX; ++i) { + if ((bm & bmarray[i]) != 0) + return i; + } + return NO_COLOR; } /* @@ -2910,11 +2995,10 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, MSNHMsgUpdateStatus update_cmd_data; int ocolor, ochar; unsigned ospecial; - long value = -1; - boolean reset_state = FALSE; logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, colormasks); +#if 0 // TODO: this code was dead ... do we need to respond to these updates? switch (idx) { case BL_RESET: reset_state = TRUE; @@ -2924,42 +3008,44 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, default: break; } +#endif if (idx >= 0) { - if (!_status_activefields[idx]) + + nhassert(idx <= SIZE(_status_fields)); + mswin_status_field * status_field = &_status_fields[idx]; + nhassert(status_field->field_index == idx); + + nhassert(idx <= SIZE(_status_strings)); + mswin_status_string * status_string = &_status_strings[idx]; + + if (!status_field->enabled) { + nhassert(status_string->str == NULL); return; - _status_percents[idx] = percent; + } + + // TODO: is color actualy color and attribute OR not? + status_field->color = color & 0xff; + status_string->color = color & 0xff; + switch (idx) { case BL_CONDITION: { + mswin_condition_field * condition_field = _condition_fields; + + nhassert(status_string->str == NULL); + cond = *condptr; - *_status_vals[idx] = '\0'; - if (cond & BL_MASK_STONE) - Strcat(_status_vals[idx], " Stone"); - if (cond & BL_MASK_SLIME) - Strcat(_status_vals[idx], " Slime"); - if (cond & BL_MASK_STRNGL) - Strcat(_status_vals[idx], " Strngl"); - if (cond & BL_MASK_FOODPOIS) - Strcat(_status_vals[idx], " FoodPois"); - if (cond & BL_MASK_TERMILL) - Strcat(_status_vals[idx], " TermIll"); - if (cond & BL_MASK_BLIND) - Strcat(_status_vals[idx], " Blind"); - if (cond & BL_MASK_DEAF) - Strcat(_status_vals[idx], " Deaf"); - if (cond & BL_MASK_STUN) - Strcat(_status_vals[idx], " Stun"); - if (cond & BL_MASK_CONF) - Strcat(_status_vals[idx], " Conf"); - if (cond & BL_MASK_HALLU) - Strcat(_status_vals[idx], " Hallu"); - if (cond & BL_MASK_LEV) - Strcat(_status_vals[idx], " Lev"); - if (cond & BL_MASK_FLY) - Strcat(_status_vals[idx], " Fly"); - if (cond & BL_MASK_RIDE) - Strcat(_status_vals[idx], " Ride"); - value = cond; + + for (int i = 0; i < BL_MASK_BITS; i++, condition_field++) { + status_string = &_condition_strings[i]; + + if (condition_field->mask & cond) { + status_string->str = condition_field->name; + status_string->color = mswin_condcolor(condition_field->mask, colormasks); + } + else + status_string->str = NULL; + } } break; case BL_GOLD: { char buf[BUFSZ]; @@ -2971,33 +3057,34 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, p = strchr(text, ':'); if (p) { strncpy(buf + 1, p, sizeof(buf) - 2); - value = atol(p + 1); } else { buf[1] = ':'; strncpy(buf + 2, text, sizeof(buf) - 2); - value = atol(text); } - Sprintf(_status_vals[idx], - _status_fieldfmt[idx] ? _status_fieldfmt[idx] : "%s", - buf); + + Sprintf(status_field->string, status_field->format ? status_field->format : "%s", buf); + nhassert(status_string->str == status_field->string); } break; default: { - value = atol(text); - Sprintf(_status_vals[idx], - _status_fieldfmt[idx] ? _status_fieldfmt[idx] : "%s", + Sprintf(status_field->string, status_field->format ? status_field->format : "%s", text); + nhassert(status_string->str == status_field->string); } break; } - _status_colors[idx] = color; + /* if we received an update for the hp field, we must update the + * bar percent and bar color for the title string */ + if (idx == BL_HP) { + mswin_status_string * title_string = &_status_strings[BL_TITLE]; + + title_string->bar_color = color; + title_string->bar_percent = percent; + + } /* 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; + update_cmd_data.status_lines = &_status_lines; SendMessage(mswin_hwnd_from_winid(WIN_STATUS), WM_MSNH_COMMAND, (WPARAM) MSNH_MSG_UPDATE_STATUS, (LPARAM) &update_cmd_data); }