detection/#terrain fix for u.uinwater
[aNetHack.git] / win / win32 / mhstatus.c
blobfce51f2685c7e8ce27ff8e3de598c7ebe95d1dc0
1 /* NetHack 3.6 mhstatus.c $NHDT-Date: 1432512810 2015/05/25 00:13:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.22 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "winMS.h"
6 #include "mhstatus.h"
7 #include "mhmsg.h"
8 #include "mhfont.h"
10 #define NHSW_LINES 2
11 #define MAXWINDOWTEXT BUFSZ
13 extern COLORREF nhcolor_to_RGB(int c); /* from mhmap */
15 typedef struct mswin_nethack_status_window {
16 int index;
17 char window_text[NHSW_LINES][MAXWINDOWTEXT + 1];
18 int n_fields;
19 const char **vals;
20 boolean *activefields;
21 int *colors;
22 } NHStatusWindow, *PNHStatusWindow;
24 #ifdef STATUS_VIA_WINDOWPORT
25 static int fieldorder1[] = { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN,
26 BL_WI, BL_CH, BL_ALIGN, BL_SCORE, -1 };
27 static int fieldorder2[] = { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX,
28 BL_ENE, BL_ENEMAX, BL_AC, BL_XP,
29 BL_EXP, BL_HD, BL_TIME, BL_HUNGER,
30 BL_CAP, BL_CONDITION, -1 };
31 static int *fieldorders[] = { fieldorder1, fieldorder2, NULL };
32 #endif /* STATUS_VIA_WINDOWPORT */
34 static TCHAR szStatusWindowClass[] = TEXT("MSNHStatusWndClass");
35 LRESULT CALLBACK StatusWndProc(HWND, UINT, WPARAM, LPARAM);
36 static void register_status_window_class(void);
37 static LRESULT onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam);
39 #define DEFAULT_COLOR_BG_STATUS COLOR_WINDOW
40 #define DEFAULT_COLOR_FG_STATUS COLOR_WINDOWTEXT
42 HWND
43 mswin_init_status_window()
45 static int run_once = 0;
46 HWND ret;
47 NHStatusWindow *data;
48 RECT rt;
50 if (!run_once) {
51 register_status_window_class();
52 run_once = 1;
55 /* get window position */
56 if (GetNHApp()->bAutoLayout) {
57 SetRect(&rt, 0, 0, 0, 0);
58 } else {
59 mswin_get_window_placement(NHW_STATUS, &rt);
62 /* create status window object */
63 ret = CreateWindow(szStatusWindowClass, NULL,
64 WS_CHILD | WS_CLIPSIBLINGS | WS_SIZEBOX,
65 rt.left, /* horizontal position of window */
66 rt.top, /* vertical position of window */
67 rt.right - rt.left, /* window width */
68 rt.bottom - rt.top, /* window height */
69 GetNHApp()->hMainWnd, NULL, GetNHApp()->hApp, NULL);
70 if (!ret)
71 panic("Cannot create status window");
73 /* Set window caption */
74 SetWindowText(ret, "Status");
76 /* create window data */
77 data = (PNHStatusWindow) malloc(sizeof(NHStatusWindow));
78 if (!data)
79 panic("out of memory");
81 ZeroMemory(data, sizeof(NHStatusWindow));
82 SetWindowLongPtr(ret, GWLP_USERDATA, (LONG_PTR) data);
84 mswin_apply_window_style(ret);
86 return ret;
89 void
90 register_status_window_class()
92 WNDCLASS wcex;
93 ZeroMemory(&wcex, sizeof(wcex));
95 wcex.style = CS_NOCLOSE;
96 wcex.lpfnWndProc = (WNDPROC) StatusWndProc;
97 wcex.cbClsExtra = 0;
98 wcex.cbWndExtra = 0;
99 wcex.hInstance = GetNHApp()->hApp;
100 wcex.hIcon = NULL;
101 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
102 wcex.hbrBackground = status_bg_brush
103 ? status_bg_brush
104 : SYSCLR_TO_BRUSH(DEFAULT_COLOR_BG_STATUS);
105 wcex.lpszMenuName = NULL;
106 wcex.lpszClassName = szStatusWindowClass;
108 RegisterClass(&wcex);
111 LRESULT CALLBACK
112 StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
114 PNHStatusWindow data;
116 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
117 switch (message) {
118 case WM_MSNH_COMMAND: {
119 switch (wParam) {
120 case MSNH_MSG_PUTSTR: {
121 PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr) lParam;
122 strncpy(data->window_text[data->index], msg_data->text,
123 MAXWINDOWTEXT);
124 data->index = (data->index + 1) % NHSW_LINES;
125 InvalidateRect(hWnd, NULL, TRUE);
126 } break;
128 case MSNH_MSG_CLEAR_WINDOW: {
129 data->index = 0;
130 ZeroMemory(data->window_text, sizeof(data->window_text));
131 InvalidateRect(hWnd, NULL, TRUE);
132 } break;
134 case MSNH_MSG_GETTEXT: {
135 PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam;
136 #ifdef STATUS_VIA_WINDOWPORT
137 int **fop;
138 int *f;
139 msg_data->buffer[0] = '\0';
140 if (data->n_fields > 0) {
141 for (fop = fieldorders; *fop; fop++) {
142 for (f = *fop; *f != -1; f++) {
143 if (data->activefields[*f])
144 strncat(msg_data->buffer, data->vals[*f],
145 msg_data->max_size
146 - strlen(msg_data->buffer));
148 strncat(msg_data->buffer, "\r\n",
149 msg_data->max_size - strlen(msg_data->buffer));
152 #else /* STATUS_VIA_WINDOWPORT */
153 strncpy(msg_data->buffer, data->window_text[0],
154 msg_data->max_size);
155 strncat(msg_data->buffer, "\r\n",
156 msg_data->max_size - strlen(msg_data->buffer));
157 strncat(msg_data->buffer, data->window_text[1],
158 msg_data->max_size - strlen(msg_data->buffer));
159 #endif /* STATUS_VIA_WINDOWPORT */
160 } break;
162 case MSNH_MSG_UPDATE_STATUS: {
163 PMSNHMsgUpdateStatus msg_data = (PMSNHMsgUpdateStatus) lParam;
164 data->n_fields = msg_data->n_fields;
165 data->vals = msg_data->vals;
166 data->activefields = msg_data->activefields;
167 data->colors = msg_data->colors;
168 InvalidateRect(hWnd, NULL, TRUE);
169 } break;
170 } /* end switch( wParam ) { */
171 } break;
173 case WM_PAINT:
174 return onWMPaint(hWnd, wParam, lParam);
176 case WM_SIZE: {
177 RECT rt;
178 GetWindowRect(hWnd, &rt);
179 ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT) &rt);
180 ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT) &rt) + 1);
181 mswin_update_window_placement(NHW_STATUS, &rt);
183 return FALSE;
185 case WM_MOVE: {
186 RECT rt;
187 GetWindowRect(hWnd, &rt);
188 ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT) &rt);
189 ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT) &rt) + 1);
190 mswin_update_window_placement(NHW_STATUS, &rt);
192 return FALSE;
194 case WM_DESTROY:
195 free(data);
196 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) 0);
197 break;
199 case WM_SETFOCUS:
200 SetFocus(GetNHApp()->hMainWnd);
201 break;
203 default:
204 return DefWindowProc(hWnd, message, wParam, lParam);
206 return 0;
209 #ifdef STATUS_VIA_WINDOWPORT
210 static LRESULT
211 onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
213 int *f;
214 int **fop;
215 SIZE sz;
216 HGDIOBJ oldFont, normalFont, boldFont;
217 TCHAR wbuf[BUFSZ];
218 COLORREF OldBg, OldFg, Bg, Fg;
219 RECT rt;
220 PAINTSTRUCT ps;
221 HDC hdc;
222 PNHStatusWindow data;
224 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
226 hdc = BeginPaint(hWnd, &ps);
227 GetClientRect(hWnd, &rt);
229 normalFont = mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE);
230 boldFont = mswin_get_font(NHW_STATUS, ATR_BOLD, hdc, FALSE);
231 oldFont = SelectObject(hdc, normalFont);
233 Bg = status_bg_brush ? status_bg_color
234 : (COLORREF) GetSysColor(DEFAULT_COLOR_BG_STATUS);
235 OldBg = SetBkColor(hdc, Bg);
237 Fg = status_fg_brush ? status_fg_color
238 : (COLORREF) GetSysColor(DEFAULT_COLOR_FG_STATUS);
239 OldFg = SetTextColor(hdc, Fg);
241 for (fop = fieldorders; *fop; fop++) {
242 LONG left = rt.left;
243 LONG cy = 0;
244 int vlen;
245 for (f = *fop; *f != -1; f++) {
246 if (((*f) >= data->n_fields) || (!data->activefields[*f]))
247 continue;
248 vlen = strlen(data->vals[*f]);
249 NH_A2W(data->vals[*f], wbuf, SIZE(wbuf));
251 if (!iflags.use_status_hilites) {
252 SelectObject(hdc, normalFont);
253 SetBkColor(hdc, Bg);
254 SetTextColor(hdc, Fg);
255 } else if (data->colors[*f] == CLR_MAX
256 || data->colors[*f] == BL_HILITE_NONE) {
257 SelectObject(hdc, normalFont);
258 SetBkColor(hdc, Bg);
259 SetTextColor(hdc, Fg);
260 } else if (data->colors[*f] > 0) {
261 SelectObject(hdc, normalFont);
262 SetBkColor(hdc, Bg);
263 SetTextColor(hdc, nhcolor_to_RGB(data->colors[*f]));
264 } else if (data->colors[*f] == BL_HILITE_INVERSE) {
265 SelectObject(hdc, normalFont);
266 SetBkColor(hdc, Fg);
267 SetTextColor(hdc, Bg);
268 } else if (data->colors[*f] == BL_HILITE_BOLD) {
269 SelectObject(hdc, boldFont);
270 SetBkColor(hdc, Bg);
271 SetTextColor(hdc, Fg);
272 } else {
273 SelectObject(hdc, normalFont);
274 SetBkColor(hdc, Bg);
275 SetTextColor(hdc, Fg);
278 GetTextExtentPoint32(hdc, wbuf, vlen, &sz);
279 DrawText(hdc, wbuf, vlen, &rt, DT_LEFT);
281 rt.left += sz.cx;
282 cy = max(cy, sz.cy);
284 rt.left = left;
285 rt.top += cy;
288 SelectObject(hdc, oldFont);
289 SetTextColor(hdc, OldFg);
290 SetBkColor(hdc, OldBg);
291 EndPaint(hWnd, &ps);
293 return 0;
295 #else
296 static LRESULT
297 onWMPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
299 int i;
300 SIZE sz;
301 HGDIOBJ oldFont;
302 TCHAR wbuf[BUFSZ];
303 COLORREF OldBg, OldFg;
304 RECT rt;
305 PAINTSTRUCT ps;
306 HDC hdc;
307 PNHStatusWindow data;
309 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
311 hdc = BeginPaint(hWnd, &ps);
312 GetClientRect(hWnd, &rt);
314 oldFont =
315 SelectObject(hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
317 OldBg = SetBkColor(hdc, status_bg_brush ? status_bg_color
318 : (COLORREF) GetSysColor(
319 DEFAULT_COLOR_BG_STATUS));
320 OldFg = SetTextColor(hdc, status_fg_brush ? status_fg_color
321 : (COLORREF) GetSysColor(
322 DEFAULT_COLOR_FG_STATUS));
324 for (i = 0; i < NHSW_LINES; i++) {
325 int wlen = strlen(data->window_text[i]);
326 NH_A2W(data->window_text[i], wbuf, SIZE(wbuf));
327 GetTextExtentPoint32(hdc, wbuf, wlen, &sz);
328 DrawText(hdc, wbuf, wlen, &rt, DT_LEFT | DT_END_ELLIPSIS);
329 rt.top += sz.cy;
332 SelectObject(hdc, oldFont);
333 SetTextColor(hdc, OldFg);
334 SetBkColor(hdc, OldBg);
335 EndPaint(hWnd, &ps);
337 return 0;
339 #endif /*STATUS_VIA_WINDOWPORT*/
341 void
342 mswin_status_window_size(HWND hWnd, LPSIZE sz)
344 TEXTMETRIC tm;
345 HGDIOBJ saveFont;
346 HDC hdc;
347 PNHStatusWindow data;
348 RECT rt;
349 SIZE text_sz;
351 GetClientRect(hWnd, &rt);
353 data = (PNHStatusWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
354 if (data) {
355 hdc = GetDC(hWnd);
356 saveFont = SelectObject(
357 hdc, mswin_get_font(NHW_STATUS, ATR_NONE, hdc, FALSE));
358 GetTextExtentPoint32(hdc, _T("W"), 1, &text_sz);
359 GetTextMetrics(hdc, &tm);
361 rt.bottom = rt.top + text_sz.cy * NHSW_LINES;
363 SelectObject(hdc, saveFont);
364 ReleaseDC(hWnd, hdc);
366 AdjustWindowRect(&rt, GetWindowLong(hWnd, GWL_STYLE), FALSE);
367 sz->cx = rt.right - rt.left;
368 sz->cy = rt.bottom - rt.top;