1 /* aNetHack 0.0.1 mhmap.c $ANH-Date: 1432512799 2015/05/25 00:13:19 $ $ANH-Branch: master $:$ANH-Revision: 1.40 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* aNetHack may be freely redistributed. See license for details. */
11 #include "patchlevel.h"
13 #define NHMAP_FONT_NAME TEXT("Terminal")
14 #define MAXWINDOWTEXT 255
16 extern short glyph2tile
[];
19 typedef struct mswin_anethack_map_window
{
20 int map
[COLNO
][ROWNO
]; /* glyph map */
22 int mapMode
; /* current map mode */
23 boolean bAsciiMode
; /* switch ASCII/tiled mode */
24 boolean bFitToScreenMode
; /* switch Fit map to screen mode on/off */
25 int xPos
, yPos
; /* scroll position */
26 int xPageSize
, yPageSize
; /* scroll page size */
27 int xCur
, yCur
; /* position of the cursor */
28 int xScrTile
, yScrTile
; /* size of display tile */
29 POINT map_orig
; /* map origin point */
30 HFONT hMapFont
; /* font for ASCII mode */
31 int xLastMouseClick
, yLastMouseClick
; /* last mouse click */
32 } NHMapWindow
, *PNHMapWindow
;
34 static TCHAR szNHMapWindowClass
[] = TEXT("MSNethackMapWndClass");
35 LRESULT CALLBACK
MapWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
36 static void register_map_window_class(void);
37 static void onMSNHCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
38 static void onMSNH_VScroll(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
39 static void onMSNH_HScroll(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
40 static void onPaint(HWND hWnd
);
41 static void onCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
);
42 static void nhcoord2display(PNHMapWindow data
, int x
, int y
, LPRECT lpOut
);
43 #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2)
44 static void nhglyph2charcolor(short glyph
, uchar
*ch
, int *color
);
46 static COLORREF
nhcolor_to_RGB(int c
);
49 mswin_init_map_window()
51 static int run_once
= 0;
56 register_map_window_class();
60 styles
= WS_CHILD
| WS_CLIPSIBLINGS
;
61 if (!GetNHApp()->bHideScrollBars
)
62 styles
|= WS_HSCROLL
| WS_VSCROLL
;
64 szNHMapWindowClass
, /* registered class name */
65 NULL
, /* window name */
66 styles
, /* window style */
67 0, /* horizontal position of window - set it later */
68 0, /* vertical position of window - set it later */
69 0, /* window width - set it later */
70 0, /* window height - set it later*/
71 GetNHApp()->hMainWnd
, /* handle to parent or owner window */
72 NULL
, /* menu handle or child identifier */
73 GetNHApp()->hApp
, /* handle to application instance */
74 NULL
); /* window-creation data */
76 panic("Cannot create map window");
82 mswin_map_stretch(HWND hWnd
, LPSIZE lpsz
, BOOL redraw
)
91 if (!IsWindow(hWnd
) || !lpsz
|| lpsz
->cx
<= 0 || lpsz
->cy
<= 0)
94 /* calculate window size */
95 GetClientRect(hWnd
, &client_rt
);
96 wnd_size
.cx
= client_rt
.right
- client_rt
.left
;
97 wnd_size
.cy
= client_rt
.bottom
- client_rt
.top
;
99 /* set new screen tile size */
100 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
102 max(1, (data
->bFitToScreenMode
? wnd_size
.cx
: lpsz
->cx
) / COLNO
);
104 max(1, (data
->bFitToScreenMode
? wnd_size
.cy
: lpsz
->cy
) / ROWNO
);
106 /* set map origin point */
108 max(0, client_rt
.left
+ (wnd_size
.cx
- data
->xScrTile
* COLNO
) / 2);
110 max(0, client_rt
.top
+ (wnd_size
.cy
- data
->yScrTile
* ROWNO
) / 2);
112 data
->map_orig
.x
-= data
->map_orig
.x
% data
->xScrTile
;
113 data
->map_orig
.y
-= data
->map_orig
.y
% data
->yScrTile
;
115 /* adjust horizontal scroll bar */
116 if (data
->bFitToScreenMode
)
117 data
->xPageSize
= COLNO
+ 1; /* disable scroll bar */
119 data
->xPageSize
= wnd_size
.cx
/ data
->xScrTile
;
121 if (data
->xPageSize
>= COLNO
) {
123 GetNHApp()->bNoHScroll
= TRUE
;
125 GetNHApp()->bNoHScroll
= FALSE
;
127 0, min(COLNO
- data
->xPageSize
+ 1, u
.ux
- data
->xPageSize
/ 2));
130 if (!GetNHApp()->bHideScrollBars
) {
131 si
.cbSize
= sizeof(si
);
132 si
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
135 si
.nPage
= data
->xPageSize
;
136 si
.nPos
= data
->xPos
;
137 SetScrollInfo(hWnd
, SB_HORZ
, &si
, TRUE
);
140 /* adjust vertical scroll bar */
141 if (data
->bFitToScreenMode
)
142 data
->yPageSize
= ROWNO
+ 1; /* disable scroll bar */
144 data
->yPageSize
= wnd_size
.cy
/ data
->yScrTile
;
146 if (data
->yPageSize
>= ROWNO
) {
148 GetNHApp()->bNoVScroll
= TRUE
;
150 GetNHApp()->bNoVScroll
= FALSE
;
152 0, min(ROWNO
- data
->yPageSize
+ 1, u
.uy
- data
->yPageSize
/ 2));
155 if (!GetNHApp()->bHideScrollBars
) {
156 si
.cbSize
= sizeof(si
);
157 si
.fMask
= SIF_RANGE
| SIF_PAGE
| SIF_POS
;
160 si
.nPage
= data
->yPageSize
;
161 si
.nPos
= data
->yPos
;
162 SetScrollInfo(hWnd
, SB_VERT
, &si
, TRUE
);
167 DeleteObject(data
->hMapFont
);
168 ZeroMemory(&lgfnt
, sizeof(lgfnt
));
169 lgfnt
.lfHeight
= -data
->yScrTile
; // height of font
170 lgfnt
.lfWidth
= -data
->xScrTile
; // average character width
171 lgfnt
.lfEscapement
= 0; // angle of escapement
172 lgfnt
.lfOrientation
= 0; // base-line orientation angle
173 lgfnt
.lfWeight
= FW_NORMAL
; // font weight
174 lgfnt
.lfItalic
= FALSE
; // italic attribute option
175 lgfnt
.lfUnderline
= FALSE
; // underline attribute option
176 lgfnt
.lfStrikeOut
= FALSE
; // strikeout attribute option
177 lgfnt
.lfCharSet
= mswin_charset(); // character set identifier
178 lgfnt
.lfOutPrecision
= OUT_DEFAULT_PRECIS
; // output precision
179 lgfnt
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
; // clipping precision
180 lgfnt
.lfQuality
= DEFAULT_QUALITY
; // output quality
181 if (iflags
.wc_font_map
&& *iflags
.wc_font_map
) {
182 lgfnt
.lfPitchAndFamily
= DEFAULT_PITCH
; // pitch and family
183 NH_A2W(iflags
.wc_font_map
, lgfnt
.lfFaceName
, LF_FACESIZE
);
185 lgfnt
.lfPitchAndFamily
= FIXED_PITCH
; // pitch and family
186 _tcsncpy(lgfnt
.lfFaceName
, NHMAP_FONT_NAME
, LF_FACESIZE
);
188 data
->hMapFont
= CreateFontIndirect(&lgfnt
);
190 mswin_cliparound(data
->xCur
, data
->yCur
);
193 InvalidateRect(hWnd
, NULL
, TRUE
);
198 mswin_map_mode(HWND hWnd
, int mode
)
204 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
205 if (mode
== data
->mapMode
)
208 oldMode
= data
->mapMode
;
209 data
->mapMode
= mode
;
211 switch (data
->mapMode
) {
212 case MAP_MODE_ASCII4x6
:
213 data
->bAsciiMode
= TRUE
;
214 data
->bFitToScreenMode
= FALSE
;
215 mapSize
.cx
= 4 * COLNO
;
216 mapSize
.cy
= 6 * ROWNO
;
219 case MAP_MODE_ASCII6x8
:
220 data
->bAsciiMode
= TRUE
;
221 data
->bFitToScreenMode
= FALSE
;
222 mapSize
.cx
= 6 * COLNO
;
223 mapSize
.cy
= 8 * ROWNO
;
226 case MAP_MODE_ASCII8x8
:
227 data
->bAsciiMode
= TRUE
;
228 data
->bFitToScreenMode
= FALSE
;
229 mapSize
.cx
= 8 * COLNO
;
230 mapSize
.cy
= 8 * ROWNO
;
233 case MAP_MODE_ASCII16x8
:
234 data
->bAsciiMode
= TRUE
;
235 data
->bFitToScreenMode
= FALSE
;
236 mapSize
.cx
= 16 * COLNO
;
237 mapSize
.cy
= 8 * ROWNO
;
240 case MAP_MODE_ASCII7x12
:
241 data
->bAsciiMode
= TRUE
;
242 data
->bFitToScreenMode
= FALSE
;
243 mapSize
.cx
= 7 * COLNO
;
244 mapSize
.cy
= 12 * ROWNO
;
247 case MAP_MODE_ASCII8x12
:
248 data
->bAsciiMode
= TRUE
;
249 data
->bFitToScreenMode
= FALSE
;
250 mapSize
.cx
= 8 * COLNO
;
251 mapSize
.cy
= 12 * ROWNO
;
254 case MAP_MODE_ASCII16x12
:
255 data
->bAsciiMode
= TRUE
;
256 data
->bFitToScreenMode
= FALSE
;
257 mapSize
.cx
= 16 * COLNO
;
258 mapSize
.cy
= 12 * ROWNO
;
261 case MAP_MODE_ASCII12x16
:
262 data
->bAsciiMode
= TRUE
;
263 data
->bFitToScreenMode
= FALSE
;
264 mapSize
.cx
= 12 * COLNO
;
265 mapSize
.cy
= 16 * ROWNO
;
268 case MAP_MODE_ASCII10x18
:
269 data
->bAsciiMode
= TRUE
;
270 data
->bFitToScreenMode
= FALSE
;
271 mapSize
.cx
= 10 * COLNO
;
272 mapSize
.cy
= 18 * ROWNO
;
275 case MAP_MODE_ASCII_FIT_TO_SCREEN
: {
277 GetClientRect(hWnd
, &client_rt
);
278 mapSize
.cx
= client_rt
.right
- client_rt
.left
;
279 mapSize
.cy
= client_rt
.bottom
- client_rt
.top
;
281 data
->bAsciiMode
= TRUE
;
282 data
->bFitToScreenMode
= TRUE
;
285 case MAP_MODE_TILES_FIT_TO_SCREEN
: {
287 GetClientRect(hWnd
, &client_rt
);
288 mapSize
.cx
= client_rt
.right
- client_rt
.left
;
289 mapSize
.cy
= client_rt
.bottom
- client_rt
.top
;
291 data
->bAsciiMode
= FALSE
;
292 data
->bFitToScreenMode
= TRUE
;
297 data
->bAsciiMode
= FALSE
;
298 data
->bFitToScreenMode
= FALSE
;
299 mapSize
.cx
= GetNHApp()->mapTile_X
* COLNO
;
300 mapSize
.cy
= GetNHApp()->mapTile_Y
* ROWNO
;
304 mswin_map_stretch(hWnd
, &mapSize
, TRUE
);
309 /* retrieve cursor position */
311 mswin_map_get_cursor(HWND hWnd
, int *x
, int *y
)
315 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
317 panic("mswin_map_get_cursor: no window data");
324 /* register window class for map window */
326 register_map_window_class()
329 ZeroMemory(&wcex
, sizeof(wcex
));
332 wcex
.style
= CS_NOCLOSE
| CS_DBLCLKS
;
333 wcex
.lpfnWndProc
= (WNDPROC
) MapWndProc
;
336 wcex
.hInstance
= GetNHApp()->hApp
;
338 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
340 CreateSolidBrush(RGB(0, 0, 0)); /* set backgroup here */
341 wcex
.lpszMenuName
= NULL
;
342 wcex
.lpszClassName
= szNHMapWindowClass
;
344 if (!RegisterClass(&wcex
)) {
345 panic("cannot register Map window class");
349 /* map window procedure */
351 MapWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
356 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
359 onCreate(hWnd
, wParam
, lParam
);
362 case WM_MSNH_COMMAND
:
363 onMSNHCommand(hWnd
, wParam
, lParam
);
371 /* transfer focus back to the main window */
372 SetFocus(GetNHApp()->hMainWnd
);
376 onMSNH_HScroll(hWnd
, wParam
, lParam
);
380 onMSNH_VScroll(hWnd
, wParam
, lParam
);
386 if (data
->bFitToScreenMode
) {
387 size
.cx
= LOWORD(lParam
);
388 size
.cy
= HIWORD(lParam
);
390 /* mapping factor is unchaged we just need to adjust scroll bars
392 size
.cx
= data
->xScrTile
* COLNO
;
393 size
.cy
= data
->yScrTile
* ROWNO
;
395 mswin_map_stretch(hWnd
, &size
, TRUE
);
399 x
= max(0, min(COLNO
, data
->xPos
400 + (LOWORD(lParam
) - data
->map_orig
.x
)
402 y
= max(0, min(ROWNO
, data
->yPos
403 + (HIWORD(lParam
) - data
->map_orig
.y
)
406 NHEVENT_MS(CLICK_1
, x
, y
);
408 data
->xLastMouseClick
= x
;
409 data
->yLastMouseClick
= y
;
412 case WM_LBUTTONDBLCLK
:
413 x
= max(0, min(COLNO
, data
->xPos
414 + (LOWORD(lParam
) - data
->map_orig
.x
)
416 y
= max(0, min(ROWNO
, data
->yPos
417 + (HIWORD(lParam
) - data
->map_orig
.y
)
420 /* if map has scrolled since the last mouse click - ignore
421 * double-click message */
422 if (data
->xLastMouseClick
== x
&& data
->yLastMouseClick
== y
) {
423 NHEVENT_MS(CLICK_1
, x
, y
);
429 DeleteObject(data
->hMapFont
);
431 SetWindowLong(hWnd
, GWL_USERDATA
, (LONG
) 0);
435 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
442 onMSNHCommand(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
447 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
449 case MSNH_MSG_PRINT_GLYPH
: {
450 PMSNHMsgPrintGlyph msg_data
= (PMSNHMsgPrintGlyph
) lParam
;
451 data
->map
[msg_data
->x
][msg_data
->y
] = msg_data
->glyph
;
453 /* invalidate the update area */
454 nhcoord2display(data
, msg_data
->x
, msg_data
->y
, &rt
);
455 InvalidateRect(hWnd
, &rt
, TRUE
);
458 case MSNH_MSG_CLIPAROUND
: {
459 PMSNHMsgClipAround msg_data
= (PMSNHMsgClipAround
) lParam
;
461 BOOL scroll_x
, scroll_y
;
462 int mcam
= iflags
.wc_scroll_margin
;
464 /* calculate if you should clip around */
466 !GetNHApp()->bNoHScroll
467 && (msg_data
->x
< (data
->xPos
+ mcam
)
468 || msg_data
->x
> (data
->xPos
+ data
->xPageSize
- mcam
));
470 !GetNHApp()->bNoVScroll
471 && (msg_data
->y
< (data
->yPos
+ mcam
)
472 || msg_data
->y
> (data
->yPos
+ data
->yPageSize
- mcam
));
474 mcam
+= iflags
.wc_scroll_amount
- 1;
475 /* get page size and center horizontally on x-position */
477 if (data
->xPageSize
<= 2 * mcam
) {
478 x
= max(0, min(COLNO
, msg_data
->x
- data
->xPageSize
/ 2));
479 } else if (msg_data
->x
< data
->xPos
+ data
->xPageSize
/ 2) {
480 x
= max(0, min(COLNO
, msg_data
->x
- mcam
));
482 x
= max(0, min(COLNO
, msg_data
->x
- data
->xPageSize
+ mcam
));
484 SendMessage(hWnd
, WM_HSCROLL
, (WPARAM
) MAKELONG(SB_THUMBTRACK
, x
),
488 /* get page size and center vertically on y-position */
490 if (data
->yPageSize
<= 2 * mcam
) {
491 y
= max(0, min(ROWNO
, msg_data
->y
- data
->yPageSize
/ 2));
492 } else if (msg_data
->y
< data
->yPos
+ data
->yPageSize
/ 2) {
493 y
= max(0, min(ROWNO
, msg_data
->y
- mcam
));
495 y
= max(0, min(ROWNO
, msg_data
->y
- data
->yPageSize
+ mcam
));
497 SendMessage(hWnd
, WM_VSCROLL
, (WPARAM
) MAKELONG(SB_THUMBTRACK
, y
),
502 case MSNH_MSG_CLEAR_WINDOW
: {
504 for (i
= 0; i
< COLNO
; i
++)
505 for (j
= 0; j
< ROWNO
; j
++) {
506 data
->map
[i
][j
] = -1;
508 InvalidateRect(hWnd
, NULL
, TRUE
);
511 case MSNH_MSG_CURSOR
: {
512 PMSNHMsgCursor msg_data
= (PMSNHMsgCursor
) lParam
;
516 /* move focus rectangle at the cursor postion */
519 nhcoord2display(data
, data
->xCur
, data
->yCur
, &rt
);
520 if (data
->bAsciiMode
) {
521 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
,
522 rt
.bottom
- rt
.top
, DSTINVERT
);
524 DrawFocusRect(hdc
, &rt
);
527 data
->xCur
= msg_data
->x
;
528 data
->yCur
= msg_data
->y
;
530 nhcoord2display(data
, data
->xCur
, data
->yCur
, &rt
);
531 if (data
->bAsciiMode
) {
532 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
,
533 rt
.bottom
- rt
.top
, DSTINVERT
);
535 DrawFocusRect(hdc
, &rt
);
538 ReleaseDC(hWnd
, hdc
);
545 onCreate(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
550 /* set window data */
551 data
= (PNHMapWindow
) malloc(sizeof(NHMapWindow
));
553 panic("out of memory");
555 ZeroMemory(data
, sizeof(NHMapWindow
));
556 for (i
= 0; i
< COLNO
; i
++)
557 for (j
= 0; j
< ROWNO
; j
++) {
558 data
->map
[i
][j
] = -1;
561 data
->bAsciiMode
= FALSE
;
563 data
->xScrTile
= GetNHApp()->mapTile_X
;
564 data
->yScrTile
= GetNHApp()->mapTile_Y
;
566 data
->xLastMouseClick
= data
->yLastMouseClick
= -1;
568 SetWindowLong(hWnd
, GWL_USERDATA
, (LONG
) data
);
583 /* get window data */
584 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
586 hDC
= BeginPaint(hWnd
, &ps
);
588 /* calculate paint rectangle */
589 if (!IsRectEmpty(&ps
.rcPaint
)) {
590 /* calculate paint rectangle */
593 + (ps
.rcPaint
.left
- data
->map_orig
.x
) / data
->xScrTile
,
596 data
->yPos
+ (ps
.rcPaint
.top
- data
->map_orig
.y
) / data
->yScrTile
,
598 paint_rt
.right
= min(
600 + (ps
.rcPaint
.right
- data
->map_orig
.x
) / data
->xScrTile
+ 1,
602 paint_rt
.bottom
= min(
604 + (ps
.rcPaint
.bottom
- data
->map_orig
.y
) / data
->yScrTile
+ 1,
607 if (data
->bAsciiMode
|| Is_rogue_level(&u
.uz
)) {
608 /* You enter a VERY primitive world! */
611 oldFont
= SelectObject(hDC
, data
->hMapFont
);
612 SetBkMode(hDC
, TRANSPARENT
);
615 for (i
= paint_rt
.left
; i
< paint_rt
.right
; i
++)
616 for (j
= paint_rt
.top
; j
< paint_rt
.bottom
; j
++)
617 if (data
->map
[i
][j
] >= 0) {
627 nhcoord2display(data
, i
, j
, &glyph_rect
);
629 #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2)
630 nhglyph2charcolor(data
->map
[i
][j
], &ch
, &color
);
631 OldFg
= SetTextColor(hDC
, nhcolor_to_RGB(color
));
633 /* rely on aNetHack core helper routine */
634 (void) mapglyph(data
->map
[i
][j
], &mgch
, &color
,
637 if (((special
& MG_PET
) && iflags
.hilite_pet
)
638 || ((special
& MG_DETECT
)
639 && iflags
.use_inverse
)) {
641 CreateSolidBrush(nhcolor_to_RGB(CLR_GRAY
));
642 FillRect(hDC
, &glyph_rect
, back_brush
);
643 DeleteObject(back_brush
);
647 OldFg
= SetTextColor(
648 hDC
, nhcolor_to_RGB(CLR_BLACK
));
652 SetTextColor(hDC
, nhcolor_to_RGB(color
));
655 OldFg
= SetTextColor(hDC
, nhcolor_to_RGB(color
));
659 DrawText(hDC
, NH_A2W(&ch
, &wch
, 1), 1, &glyph_rect
,
660 DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
661 SetTextColor(hDC
, OldFg
);
663 SelectObject(hDC
, oldFont
);
665 /* prepare tiles DC for mapping */
666 tileDC
= CreateCompatibleDC(hDC
);
667 saveBmp
= SelectObject(tileDC
, GetNHApp()->bmpMapTiles
);
670 for (i
= paint_rt
.left
; i
< paint_rt
.right
; i
++)
671 for (j
= paint_rt
.top
; j
< paint_rt
.bottom
; j
++)
672 if (data
->map
[i
][j
] >= 0) {
677 ntile
= glyph2tile
[data
->map
[i
][j
]];
678 t_x
= (ntile
% GetNHApp()->mapTilesPerLine
)
679 * GetNHApp()->mapTile_X
;
680 t_y
= (ntile
/ GetNHApp()->mapTilesPerLine
)
681 * GetNHApp()->mapTile_Y
;
683 nhcoord2display(data
, i
, j
, &glyph_rect
);
685 StretchBlt(hDC
, glyph_rect
.left
, glyph_rect
.top
,
686 data
->xScrTile
, data
->yScrTile
, tileDC
,
687 t_x
, t_y
, GetNHApp()->mapTile_X
,
688 GetNHApp()->mapTile_Y
, SRCCOPY
);
689 if (glyph_is_pet(data
->map
[i
][j
])
690 && iflags
.wc_hilite_pet
) {
691 /* apply pet mark transparently over
694 HBITMAP bmPetMarkOld
;
696 /* this is DC for petmark bitmap */
697 hdcPetMark
= CreateCompatibleDC(hDC
);
698 bmPetMarkOld
= SelectObject(
699 hdcPetMark
, GetNHApp()->bmpPetMark
);
701 nhapply_image_transparent(
702 hDC
, glyph_rect
.left
, glyph_rect
.top
,
703 data
->xScrTile
, data
->yScrTile
, hdcPetMark
, 0,
704 0, TILE_X
, TILE_Y
, TILE_BK_COLOR
);
705 SelectObject(hdcPetMark
, bmPetMarkOld
);
706 DeleteDC(hdcPetMark
);
709 SelectObject(tileDC
, saveBmp
);
713 /* draw focus rect */
714 nhcoord2display(data
, data
->xCur
, data
->yCur
, &paint_rt
);
715 if (data
->bAsciiMode
) {
716 PatBlt(hDC
, paint_rt
.left
, paint_rt
.top
,
717 paint_rt
.right
- paint_rt
.left
,
718 paint_rt
.bottom
- paint_rt
.top
, DSTINVERT
);
720 DrawFocusRect(hDC
, &paint_rt
);
728 onMSNH_VScroll(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
735 /* get window data */
736 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
738 switch (LOWORD(wParam
)) {
739 /* User clicked shaft left of the scroll box. */
741 yNewPos
= data
->yPos
- data
->yPageSize
;
744 /* User clicked shaft right of the scroll box. */
746 yNewPos
= data
->yPos
+ data
->yPageSize
;
749 /* User clicked the left arrow. */
751 yNewPos
= data
->yPos
- 1;
754 /* User clicked the right arrow. */
756 yNewPos
= data
->yPos
+ 1;
759 /* User dragged the scroll box. */
761 yNewPos
= HIWORD(wParam
);
765 yNewPos
= data
->yPos
;
768 yNewPos
= max(0, min(ROWNO
- data
->yPageSize
+ 1, yNewPos
));
769 if (yNewPos
== data
->yPos
)
772 yDelta
= yNewPos
- data
->yPos
;
773 data
->yPos
= yNewPos
;
775 ScrollWindowEx(hWnd
, 0, -data
->yScrTile
* yDelta
, (CONST RECT
*) NULL
,
776 (CONST RECT
*) NULL
, (HRGN
) NULL
, (LPRECT
) NULL
,
777 SW_INVALIDATE
| SW_ERASE
);
779 if (!GetNHApp()->bHideScrollBars
) {
780 si
.cbSize
= sizeof(si
);
782 si
.nPos
= data
->yPos
;
783 SetScrollInfo(hWnd
, SB_VERT
, &si
, TRUE
);
789 onMSNH_HScroll(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
796 /* get window data */
797 data
= (PNHMapWindow
) GetWindowLong(hWnd
, GWL_USERDATA
);
799 switch (LOWORD(wParam
)) {
800 /* User clicked shaft left of the scroll box. */
802 xNewPos
= data
->xPos
- data
->xPageSize
;
805 /* User clicked shaft right of the scroll box. */
807 xNewPos
= data
->xPos
+ data
->xPageSize
;
810 /* User clicked the left arrow. */
812 xNewPos
= data
->xPos
- 1;
815 /* User clicked the right arrow. */
817 xNewPos
= data
->xPos
+ 1;
820 /* User dragged the scroll box. */
822 xNewPos
= HIWORD(wParam
);
826 xNewPos
= data
->xPos
;
829 xNewPos
= max(0, min(COLNO
- data
->xPageSize
+ 1, xNewPos
));
830 if (xNewPos
== data
->xPos
)
833 xDelta
= xNewPos
- data
->xPos
;
834 data
->xPos
= xNewPos
;
836 ScrollWindowEx(hWnd
, -data
->xScrTile
* xDelta
, 0, (CONST RECT
*) NULL
,
837 (CONST RECT
*) NULL
, (HRGN
) NULL
, (LPRECT
) NULL
,
838 SW_INVALIDATE
| SW_ERASE
);
840 if (!GetNHApp()->bHideScrollBars
) {
841 si
.cbSize
= sizeof(si
);
843 si
.nPos
= data
->xPos
;
844 SetScrollInfo(hWnd
, SB_HORZ
, &si
, TRUE
);
848 /* map anethack map coordinates to the screen location */
850 nhcoord2display(PNHMapWindow data
, int x
, int y
, LPRECT lpOut
)
852 lpOut
->left
= (x
- data
->xPos
) * data
->xScrTile
+ data
->map_orig
.x
;
853 lpOut
->top
= (y
- data
->yPos
) * data
->yScrTile
+ data
->map_orig
.y
;
854 lpOut
->right
= lpOut
->left
+ data
->xScrTile
;
855 lpOut
->bottom
= lpOut
->top
+ data
->yScrTile
;
858 #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2)
859 /* map glyph to character/color combination */
861 nhglyph2charcolor(short g
, uchar
*ch
, int *color
)
866 #define zap_color(n) *color = iflags.use_color ? zapcolors[n] : NO_COLOR
867 #define cmap_color(n) *color = iflags.use_color ? defsyms[n].color : NO_COLOR
868 #define obj_color(n) \
869 *color = iflags.use_color ? objects[n].oc_color : NO_COLOR
870 #define mon_color(n) *color = iflags.use_color ? mons[n].mcolor : NO_COLOR
871 #define pet_color(n) *color = iflags.use_color ? mons[n].mcolor : NO_COLOR
872 #define warn_color(n) \
873 *color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR
875 #else /* no text color */
878 #define cmap_color(n)
882 #define warn_color(c)
886 if ((offset
= (g
- GLYPH_WARNING_OFF
)) >= 0) { /* a warning flash */
887 *ch
= showsyms
[offset
+ SYM_OFF_W
];
889 } else if ((offset
= (g
- GLYPH_SWALLOW_OFF
)) >= 0) { /* swallow */
890 /* see swallow_to_glyph() in display.c */
891 *ch
= (uchar
) showsyms
[(S_sw_tl
+ (offset
& 0x7)) + SYM_OFF_P
];
892 mon_color(offset
>> 3);
893 } else if ((offset
= (g
- GLYPH_ZAP_OFF
)) >= 0) { /* zap beam */
894 /* see zapdir_to_glyph() in display.c */
895 *ch
= showsyms
[(S_vbeam
+ (offset
& 0x3)) + SYM_OFF_P
];
896 zap_color((offset
>> 2));
897 } else if ((offset
= (g
- GLYPH_CMAP_OFF
)) >= 0) { /* cmap */
898 *ch
= showsyms
[offset
+ SYM_OFF_P
];
900 } else if ((offset
= (g
- GLYPH_OBJ_OFF
)) >= 0) { /* object */
901 *ch
= showsyms
[(int) objects
[offset
].oc_class
+ SYM_OFF_O
];
903 } else if ((offset
= (g
- GLYPH_BODY_OFF
)) >= 0) { /* a corpse */
904 *ch
= showsyms
[(int) objects
[CORPSE
].oc_class
+ SYM_OFF_O
];
906 } else if ((offset
= (g
- GLYPH_PET_OFF
)) >= 0) { /* a pet */
907 *ch
= showsyms
[(int) mons
[offset
].mlet
+ SYM_OFF_M
];
909 } else { /* a monster */
910 *ch
= showsyms
[(int) mons
[g
].mlet
+ SYM_OFF_M
];
913 // end of wintty code
917 /* map anethack color to RGB */
919 nhcolor_to_RGB(int c
)
923 return RGB(0x55, 0x55, 0x55);
925 return RGB(0xFF, 0x00, 0x00);
927 return RGB(0x00, 0x80, 0x00);
929 return RGB(0xA5, 0x2A, 0x2A);
931 return RGB(0x00, 0x00, 0xFF);
933 return RGB(0xFF, 0x00, 0xFF);
935 return RGB(0x00, 0xFF, 0xFF);
937 return RGB(0xC0, 0xC0, 0xC0);
939 return RGB(0xFF, 0xFF, 0xFF);
941 return RGB(0xFF, 0xA5, 0x00);
942 case CLR_BRIGHT_GREEN
:
943 return RGB(0x00, 0xFF, 0x00);
945 return RGB(0xFF, 0xFF, 0x00);
946 case CLR_BRIGHT_BLUE
:
947 return RGB(0x00, 0xC0, 0xFF);
948 case CLR_BRIGHT_MAGENTA
:
949 return RGB(0xFF, 0x80, 0xFF);
950 case CLR_BRIGHT_CYAN
:
951 return RGB(0x80, 0xFF, 0xFF); /* something close to aquamarine */
953 return RGB(0xFF, 0xFF, 0xFF);
955 return RGB(0x00, 0x00, 0x00); /* black */
959 /* apply bitmap pointed by sourceDc transparently over
960 bitmap pointed by hDC */
962 nhapply_image_transparent(HDC hDC
, int x
, int y
, int width
, int height
,
963 HDC sourceDC
, int s_x
, int s_y
, int s_width
,
964 int s_height
, COLORREF cTransparent
)
966 TransparentImage(hDC
, x
, y
, width
, height
, sourceDC
, s_x
, s_y
, s_width
,
967 s_height
, cTransparent
);