]> granicus.if.org Git - nethack/commitdiff
win32_gui: implement STATUS_VIA_WINDOWPORT and STATUS_HILITES
authorAlex Kompel <barbos+nethack@gmail.com>
Sat, 18 Apr 2015 05:14:04 +0000 (22:14 -0700)
committerAlex Kompel <barbos+nethack@gmail.com>
Sat, 18 Apr 2015 05:14:04 +0000 (22:14 -0700)
src/botl.c
win/win32/mhfont.c
win/win32/mhmsg.h
win/win32/mhstatus.c
win/win32/mswproc.c
win/win32/winMS.h

index 99fad4a32b542c18048e9c9cf341576cea476462..976c1aca84b8af678170569ebde869b1fc2602d2 100644 (file)
@@ -925,7 +925,7 @@ assign_hilite(sa,sb,sc,sd)
 char *sa, *sb, *sc, *sd;
 {
        char *tmp, *how;
-       int i, dt, idx = -1;
+       int i = -1, dt = -1, idx = -1;
        int coloridx[2] = {-1, -1};
        boolean inverse[2] = {FALSE, FALSE};
        boolean bold[2]    = {FALSE, FALSE};
index 7cebb921b1ebba8a7c9b6934c2b5ca1cfe8ba7dc..d7a34ba4156530bd4b0a36f70dfeeff7ce0d3147 100644 (file)
@@ -77,11 +77,12 @@ HGDIOBJ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
 
        switch(win_type) {
        case NHW_STATUS:
-               lgfnt.lfHeight                  =       -iflags.wc_fontsiz_status*GetDeviceCaps(hdc, LOGPIXELSY)/72;     // height of font
+               font_size = (attr==ATR_BOLD)? iflags.wc_fontsiz_status+1 : iflags.wc_fontsiz_status;
+               lgfnt.lfHeight                  =       -font_size*GetDeviceCaps(hdc, LOGPIXELSY)/72;    // height of font
                lgfnt.lfWidth                   =       0;                                   // average character width
                lgfnt.lfEscapement              =       0;                                       // angle of escapement
                lgfnt.lfOrientation             =       0;                                       // base-line orientation angle
-               lgfnt.lfWeight                  =       FW_BOLD;             // font weight
+               lgfnt.lfWeight                  =       (attr==ATR_BOLD)? FW_BOLD : FW_NORMAL;             // font weight
                lgfnt.lfItalic                  =       FALSE;                   // italic attribute option
                lgfnt.lfUnderline               =       FALSE;                       // underline attribute option
                lgfnt.lfStrikeOut               =       FALSE;                       // strikeout attribute option
index 8e48a3b01c333814c8255f3f3051d945a9680253..4999f9855fa24c26f4108ee77529da1ab934f441 100644 (file)
@@ -22,6 +22,7 @@
 #define MSNH_MSG_DIED                  109
 #define MSNH_MSG_CARET                 110
 #define MSNH_MSG_GETTEXT               111
+#define MSNH_MSG_UPDATE_STATUS 112
 
 typedef struct mswin_nhmsg_add_wnd {
   winid                  wid;
@@ -68,5 +69,12 @@ typedef struct mswin_nhmsg_get_text {
        char    buffer[];
 } MSNHMsgGetText, *PMSNHMsgGetText;
 
+typedef struct mswin_nhmsg_update_status {
+       int                             n_fields;
+       const char**    vals;
+       boolean*                activefields;
+       int*                    colors;
+} MSNHMsgUpdateStatus, *PMSNHMsgUpdateStatus;
+
 #endif
 
index 05a4c57e8d16f37e9375bf4b7e0cd5bef3daf64c..05f3836a00d813e5c4badc0ce8803cde34e95cea 100644 (file)
 #define NHSW_LINES    2
 #define MAXWINDOWTEXT BUFSZ
 
+extern COLORREF nhcolor_to_RGB (int c); /* from mhmap */
+
 typedef struct mswin_nethack_status_window {
-       int   index;
-       char  window_text[NHSW_LINES][MAXWINDOWTEXT+1];
+       int                     index;
+       char                    window_text[NHSW_LINES][MAXWINDOWTEXT+1];
+       int                             n_fields;
+       const char**    vals;
+       boolean*                activefields;
+       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,
+        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};
+#endif /*  STATUS_VIA_WINDOWPORT */
+
 static TCHAR szStatusWindowClass[] = TEXT("MSNHStatusWndClass");
 LRESULT CALLBACK       StatusWndProc(HWND, UINT, WPARAM, LPARAM);
 static void register_status_window_class(void);
+static LRESULT  onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);
 
 #define DEFAULT_COLOR_BG_STATUS        COLOR_WINDOW
 #define DEFAULT_COLOR_FG_STATUS        COLOR_WINDOWTEXT
@@ -91,9 +111,6 @@ void register_status_window_class()
     
 LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-       RECT rt;
-       PAINTSTRUCT ps;
-       HDC hdc;
        PNHStatusWindow data;
        
        data = (PNHStatusWindow)GetWindowLongPtr(hWnd, GWLP_USERDATA);
@@ -118,43 +135,39 @@ LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
 
                case MSNH_MSG_GETTEXT: {
                        PMSNHMsgGetText msg_data = (PMSNHMsgGetText)lParam;
+#ifdef STATUS_VIA_WINDOWPORT
+                       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) );
+                               }
+                       }
+#else /*  STATUS_VIA_WINDOWPORT */                     
                        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 */
+               } break;
+
+               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->colors = msg_data->colors;
+                       InvalidateRect(hWnd, NULL, TRUE);
                } break;
-               
                } /* end switch( wParam ) { */
        } break;
 
-       case WM_PAINT: {
-                   int i;
-                       SIZE sz;
-                       HGDIOBJ oldFont;
-                       TCHAR wbuf[BUFSZ];
-                       COLORREF OldBg, OldFg;
-
-                       hdc = BeginPaint(hWnd, &ps);
-                       GetClientRect(hWnd, &rt);
-                       
-                       oldFont = SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
-
-                       OldBg = SetBkColor(hdc, status_bg_brush 
-                               ? status_bg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_BG_STATUS));
-                       OldFg = SetTextColor(hdc, status_fg_brush 
-                               ? status_fg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_FG_STATUS));
-                       
-                       for(i=0; i<NHSW_LINES; i++ ) {
-                               GetTextExtentPoint32(hdc, NH_A2W(data->window_text[i], wbuf, sizeof(wbuf)), strlen(data->window_text[i]), &sz);
-                               NH_A2W(data->window_text[i], wbuf, BUFSZ);
-                               DrawText(hdc, wbuf, strlen(data->window_text[i]), &rt, DT_LEFT | DT_END_ELLIPSIS);
-                               rt.top += sz.cy;
-                       }
-
-                       SelectObject(hdc, oldFont);
-                       SetTextColor (hdc, OldFg);
-                       SetBkColor (hdc, OldBg);
-                       EndPaint(hWnd, &ps);
-               } break;
+       case WM_PAINT: 
+               return onWMPaint(hWnd, wParam, lParam);
 
        case WM_SIZE: {
                RECT    rt;
@@ -187,6 +200,125 @@ LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
    return 0;
 }
 
+#ifdef STATUS_VIA_WINDOWPORT
+static LRESULT onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+       int* f;
+       int** fop;
+       SIZE sz;
+       HGDIOBJ oldFont, normalFont, boldFont;
+       TCHAR wbuf[BUFSZ];
+       COLORREF OldBg, OldFg, Bg, Fg;
+       RECT rt;
+       PAINTSTRUCT ps;
+       HDC hdc;
+       PNHStatusWindow data;
+       
+       data = (PNHStatusWindow)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+       hdc = BeginPaint(hWnd, &ps);
+       GetClientRect(hWnd, &rt);
+       
+       normalFont = mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE);
+       boldFont = mswin_get_font(NHW_STATUS, ATR_BOLD, hdc, FALSE);
+       oldFont = SelectObject(hdc, normalFont);
+
+       Bg = status_bg_brush? status_bg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_BG_STATUS);
+       OldBg = SetBkColor(hdc, Bg);
+       
+       Fg = status_fg_brush? status_fg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_FG_STATUS);
+       OldFg = SetTextColor(hdc, Fg);
+       
+       for(fop = fieldorders; *fop; fop++) {
+               LONG left = rt.left;
+               LONG cy = 0;
+               int vlen;
+               for(f=*fop; *f!=-1; f++) {
+                       if( ((*f)>= data->n_fields) || (!data->activefields[*f])) continue;
+               vlen = strlen(data->vals[*f]);
+                       NH_A2W(data->vals[*f], wbuf, SIZE(wbuf));
+                       
+                       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);
+                       }
+                       
+                       GetTextExtentPoint32(hdc, wbuf, vlen, &sz);
+                       DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
+                       
+                       rt.left += sz.cx;
+                       cy = max(cy, sz.cy);
+               }
+               rt.left = left;
+               rt.top += cy;
+       }
+
+       SelectObject(hdc, oldFont);
+       SetTextColor (hdc, OldFg);
+       SetBkColor (hdc, OldBg);
+       EndPaint(hWnd, &ps);
+       
+       return 0;
+}
+#else
+static LRESULT  onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+       int i;
+       SIZE sz;
+       HGDIOBJ oldFont;
+       TCHAR wbuf[BUFSZ];
+       COLORREF OldBg, OldFg;
+       RECT rt;
+       PAINTSTRUCT ps;
+       HDC hdc;
+       PNHStatusWindow data;
+       
+       data = (PNHStatusWindow)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+       hdc = BeginPaint(hWnd, &ps);
+       GetClientRect(hWnd, &rt);
+       
+       oldFont = SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
+
+       OldBg = SetBkColor(hdc, status_bg_brush 
+               ? status_bg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_BG_STATUS));
+       OldFg = SetTextColor(hdc, status_fg_brush 
+               ? status_fg_color : (COLORREF)GetSysColor(DEFAULT_COLOR_FG_STATUS));
+       
+       for(i=0; i<NHSW_LINES; i++ ) {
+               int wlen = strlen(data->window_text[i]);
+               NH_A2W(data->window_text[i], wbuf, SIZE(wbuf));
+               GetTextExtentPoint32(hdc, wbuf, wlen, &sz);
+               DrawText(hdc, wbuf, wlen, &rt, DT_LEFT | DT_END_ELLIPSIS);
+               rt.top += sz.cy;
+       }
+
+       SelectObject(hdc, oldFont);
+       SetTextColor (hdc, OldFg);
+       SetBkColor (hdc, OldBg);
+       EndPaint(hWnd, &ps);
+       
+       return 0;
+}
+#endif /*STATUS_VIA_WINDOWPORT*/
+
 void mswin_status_window_size (HWND hWnd, LPSIZE sz)
 {
     TEXTMETRIC tm;
index b612f79aa6e702d6c5d752dac275cedac6c14aaf..5cdd4bd5dd9d888e0b470c5956c7fc2dacbb74e3 100644 (file)
@@ -12,6 +12,7 @@
 #include "dlb.h"
 #include "func_tab.h"   /* for extended commands */
 #include "winMS.h"
+#include <assert.h>
 #include "mhmap.h"
 #include "mhstatus.h"
 #include "mhtext.h"
@@ -29,8 +30,6 @@
 
 #define LLEN 128
 
-extern winid WIN_STATUS;
-
 #define NHTRACE_LOG "nhtrace.log"
 
 #ifdef _DEBUG
@@ -129,12 +128,12 @@ struct window_procs mswin_procs = {
     mswin_getmsghistory,
     mswin_putmsghistory,
 #ifdef STATUS_VIA_WINDOWPORT
-    genl_status_init,
-    genl_status_finish,
-    genl_status_enablefield,
-    genl_status_update,
+    mswin_status_init,
+    mswin_status_finish,
+    mswin_status_enablefield,
+    mswin_status_update,
 # ifdef STATUS_HILITES
-    genl_status_threshold,
+    mswin_status_threshold,
 # endif
 #endif
     genl_can_suspend_yes,
@@ -1823,7 +1822,8 @@ void mswin_outrip(winid wid, int how, time_t when)
 void mswin_preference_update(const char *pref)
 {
        HDC hdc;
-
+       int i;
+       
        if( stricmp( pref, "font_menu")==0 ||
                stricmp( pref, "font_size_menu")==0 ) {
                if( iflags.wc_fontsiz_menu<NHFONT_SIZE_MIN || 
@@ -1859,7 +1859,12 @@ void mswin_preference_update(const char *pref)
                mswin_get_font(NHW_STATUS, ATR_INVERSE, hdc, TRUE);
                ReleaseDC(GetNHApp()->hMainWnd, hdc);
 
-               InvalidateRect(mswin_hwnd_from_winid(WIN_STATUS), NULL, TRUE);
+               for (i=1; i<MAXWINDOWS; i++) {
+                       if (GetNHApp()->windowlist[i].type == NHW_STATUS 
+                       && GetNHApp()->windowlist[i].win != NULL) {
+                               InvalidateRect(GetNHApp()->windowlist[i].win, NULL, TRUE);
+                       }
+               }
                mswin_layout_main_window(NULL);
                return;
        }
@@ -2594,3 +2599,274 @@ int 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 boolean _status_activefields[MAXBLSTATS];
+extern winid WIN_STATUS;
+
+# ifdef STATUS_HILITES
+typedef struct hilite_data_struct {
+       int thresholdtype;
+       anything threshold;
+       int behavior;
+       int under;
+       int over;
+} hilite_data_t;
+static hilite_data_t _status_hilites[MAXBLSTATS];
+#endif /* STATUS_HILITES */
+/*
+status_init()   -- core calls this to notify the window port that a status
+                  display is required. The window port should perform 
+                  the necessary initialization in here, allocate memory, etc.
+*/
+void
+mswin_status_init(void)
+{
+       logDebug("mswin_status_init()\n");
+       int i;
+       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 */
+# ifdef STATUS_HILITES
+               _status_hilites[i].thresholdtype = 0;
+               _status_hilites[i].behavior = BL_TH_NONE;
+               _status_hilites[i].under = BL_HILITE_NONE;
+               _status_hilites[i].over = BL_HILITE_NONE;
+#endif /* STATUS_HILITES */
+       }
+       /* Use a window for the genl version; backward port compatibility */
+       WIN_STATUS = create_nhwindow(NHW_STATUS);
+       display_nhwindow(WIN_STATUS, FALSE);
+}
+
+/*
+status_finish() -- called when it is time for the window port to tear down
+                  the status display and free allocated memory, etc.
+*/
+void
+mswin_status_finish(void)
+{
+       logDebug("mswin_status_finish()\n");
+       /* tear down routine */
+       int i;
+
+       /* 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;
+       }
+}
+
+/*
+status_enablefield(int fldindex, char fldname, char fieldfmt, boolean enable)   
+                -- notifies the window port which fields it is authorized to
+                  display.
+               -- This may be called at any time, and is used
+                  to disable as well as enable fields, depending on the 
+                  value of the final argument (TRUE = enable).
+               -- fldindex could be 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
+               -- There are MAXBLSTATS status fields (from botl.h)
+*/
+void
+mswin_status_enablefield(int fieldidx, const char *nm, const char *fmt, boolean enable)
+{
+       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;
+}
+
+# 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)
+               -- update the value of a status field.
+               -- the fldindex identifies which field is changing and
+                  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
+               -- fldindex could also be BL_FLUSH (-1), which is not really
+                  a field index, but is a special trigger to tell the 
+                  windowport that it should redisplay all its status fields,
+                  even if no changes have been presented to it.
+               -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
+                  If fldindex is BL_CONDITION, then ptr is a long value with
+                  any or none of the following bits set (from botl.h):
+                       BL_MASK_BLIND           0x00000001L
+                       BL_MASK_CONF            0x00000002L
+                       BL_MASK_FOODPOIS        0x00000004L
+                       BL_MASK_ILL             0x00000008L
+                       BL_MASK_HALLU           0x00000010L
+                       BL_MASK_STUNNED         0x00000020L
+                       BL_MASK_SLIMED          0x00000040L
+               -- The value passed for BL_GOLD includes a leading
+                  symbol for GOLD "$:nnn". If the window port needs to use 
+                  the textual gold amount without the leading "$:" the port 
+                  will have to add 2 to the passed "ptr" for the BL_GOLD case.
+*/
+void
+mswin_status_update(int idx, genericptr_t ptr, int chg, int percent)
+{
+       logDebug("mswin_status_update(%d, %p, %d, %d)\n", idx, ptr, chg, percent);
+       long cond, *condptr = (long *)ptr;
+       char *text = (char *)ptr;
+       MSNHMsgUpdateStatus update_cmd_data;
+       int ocolor, ochar;
+       unsigned ospecial;
+       long value = -1;
+       
+       if (idx != BL_FLUSH) {
+           if (!_status_activefields[idx]) return;
+           switch(idx) {
+               case BL_CONDITION: {
+                       cond = *condptr;
+                       *_status_vals[idx] = '\0';
+                       if (cond & BL_MASK_BLIND) Strcat(_status_vals[idx], " Blind");
+                       if (cond & BL_MASK_CONF) Strcat(_status_vals[idx], " Conf");
+                       if (cond & BL_MASK_FOODPOIS)
+                               Strcat(_status_vals[idx], " FoodPois");
+                       if (cond & BL_MASK_ILL) Strcat(_status_vals[idx], " Ill");
+                       if (cond & BL_MASK_STUNNED) Strcat(_status_vals[idx], " Stun");
+                       if (cond & BL_MASK_HALLU) Strcat(_status_vals[idx], " Hallu");
+                       if (cond & BL_MASK_SLIMED) Strcat(_status_vals[idx], " Slime");
+                       value = cond;
+               } break;
+               case BL_GOLD: { 
+                       char buf[BUFSZ];
+                       char* p;
+                       ZeroMemory(buf, sizeof(buf));
+                       mapglyph(objnum_to_glyph(GOLD_PIECE), &ochar, &ocolor, &ospecial, 0, 0);
+                       buf[0] = ochar;
+                       p = strchr(text, ':');
+                       if(p) strncpy(buf+1, p, sizeof(buf)-2);
+                       value = atol(buf);
+                       Sprintf(_status_vals[idx],
+                       _status_fieldfmt[idx] ? _status_fieldfmt[idx] : "%s", buf);
+               } break;
+               default: {
+                       value = atol(text);
+                       Sprintf(_status_vals[idx],
+                       _status_fieldfmt[idx] ? _status_fieldfmt[idx] : "%s", text);
+               } break;
+           }
+       }
+
+# 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 */
+       
+       /* 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.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*/
index b3c33faa7c97fb38d1e476237c66c64aed93abb5..567503e5fa21db88ca5b6e03be33c69f9d994870 100644 (file)
@@ -164,6 +164,17 @@ 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*/
+
 /* helper function */
 HWND mswin_hwnd_from_winid(winid wid);
 winid mswin_winid_from_type(int type);