From: nethack.allison Date: Fri, 18 Jan 2002 00:42:04 +0000 (+0000) Subject: From : a couple of improvements to the user interface: X-Git-Tag: MOVE2GIT~3459 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35b46238fc1af01da12d2f107e81f3a267a24710;p=nethack From : a couple of improvements to the user interface: - fixed charset value for fonts - wrap long lines in the message window (there is a #define to switch it on and off) - multiple display modes for map --- diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index a5c5ae76c..2d2891927 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -10,6 +10,7 @@ #include "mhmenu.h" #include "mhstatus.h" #include "mhmsgwnd.h" +#include "mhmap.h" #define MAX_LOADSTRING 100 @@ -25,6 +26,9 @@ LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); static LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam); static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam); static void register_main_window_class(); +static void select_map_mode(int map_mode); +static int menuid2mapmode(int menuid); +static int mapmode2menuid(int map_mode); HWND mswin_init_main_window () { static int run_once = 0; @@ -202,7 +206,12 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) /* new window was just added */ case MSNH_MSG_ADDWND: { PMSNHMsgAddWnd msg_param = (PMSNHMsgAddWnd)lParam; - HWND child = GetNHApp()->windowlist[msg_param->wid].win; + HWND child; + + if( GetNHApp()->windowlist[msg_param->wid].type == NHW_MAP ) + select_map_mode(GetNHApp()->mapDisplayMode); + + child = GetNHApp()->windowlist[msg_param->wid].win; if( child ) mswin_layout_main_window(child); } break; @@ -323,7 +332,21 @@ LRESULT onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case IDM_SAVE: dosave(); break; - + + case IDM_MAP_TILES: + case IDM_MAP_ASCII4X6: + case IDM_MAP_ASCII6X8: + case IDM_MAP_ASCII8X8: + case IDM_MAP_ASCII16X8: + case IDM_MAP_ASCII7X12: + case IDM_MAP_ASCII8X12: + case IDM_MAP_ASCII12X16: + case IDM_MAP_ASCII16X12: + case IDM_MAP_ASCII10X18: + case IDM_MAP_FIT_TO_SCREEN: + select_map_mode(menuid2mapmode(wmId)); + break; + case IDM_HELP_LONG: display_file(HELP, TRUE); break; @@ -420,3 +443,55 @@ LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; } +void select_map_mode(int mode) +{ + CheckMenuRadioItem( + GetMenu(GetNHApp()->hMainWnd), + IDM_MAP_TILES, + IDM_MAP_FIT_TO_SCREEN, + mapmode2menuid(mode), + MF_BYCOMMAND); + + /* override for Rogue level */ +#ifdef REINCARNATION + if( Is_rogue_level(&u.uz) ) return; +#endif + + GetNHApp()->mapDisplayMode = mode; + mswin_map_mode(mswin_hwnd_from_winid(WIN_MAP), mode); +} + +static struct t_menu2mapmode { + int menuID; + int mapMode; +} _menu2mapmode[] = +{ + { IDM_MAP_TILES, NHMAP_VIEW_TILES }, + { IDM_MAP_ASCII4X6, NHMAP_VIEW_ASCII4x6 }, + { IDM_MAP_ASCII6X8, NHMAP_VIEW_ASCII6x8 }, + { IDM_MAP_ASCII8X8, NHMAP_VIEW_ASCII8x8 }, + { IDM_MAP_ASCII16X8, NHMAP_VIEW_ASCII16x8 }, + { IDM_MAP_ASCII7X12, NHMAP_VIEW_ASCII7x12 }, + { IDM_MAP_ASCII8X12, NHMAP_VIEW_ASCII8x12 }, + { IDM_MAP_ASCII12X16, NHMAP_VIEW_ASCII12x16 }, + { IDM_MAP_ASCII16X12, NHMAP_VIEW_ASCII16x12 }, + { IDM_MAP_ASCII10X18, NHMAP_VIEW_ASCII10x18 }, + { IDM_MAP_FIT_TO_SCREEN, NHMAP_VIEW_FIT_TO_SCREEN }, + { -1, -1 } +}; + +int menuid2mapmode(int menuid) +{ + struct t_menu2mapmode* p; + for( p = _menu2mapmode; p->mapMode!=-1; p++ ) + if(p->menuID==menuid ) return p->mapMode; + return -1; +} + +int mapmode2menuid(int map_mode) +{ + struct t_menu2mapmode* p; + for( p = _menu2mapmode; p->mapMode!=-1; p++ ) + if(p->mapMode==map_mode ) return p->menuID; + return -1; +} diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index bf226571b..39520ad2d 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -3,21 +3,28 @@ #include "winMS.h" #include "resource.h" -#include "mhstatus.h" +#include "mhmap.h" #include "mhmsg.h" #include "mhinput.h" #include "mhfont.h" #define MAXWINDOWTEXT 255 + extern short glyph2tile[]; /* map window data */ typedef struct mswin_nethack_map_window { int map[COLNO][ROWNO]; /* glyph map */ - int xPos, yPos; - int xPageSize, yPageSize; - int xCur, yCur; + int mapMode; /* current map mode */ + boolean bAsciiMode; /* switch ASCII/tiled mode */ + int xPos, yPos; /* scroll position */ + int xPageSize, yPageSize; /* scroll page size */ + int xCur, yCur; /* position of the cursor */ + int xScrTile, yScrTile; /* size of display tile */ + POINT map_orig; /* map origin point */ + + HFONT hMapFont; /* font for ASCII mode */ } NHMapWindow, *PNHMapWindow; static TCHAR szNHMapWindowClass[] = TEXT("MSNethackMapWndClass"); @@ -28,9 +35,9 @@ static void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam); static void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam); static void onPaint(HWND hWnd); static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); -#ifdef TEXTCOLOR +static void nhcoord2display(PNHMapWindow data, int x, int y, LPRECT lpOut); +static void nhglyph2charcolor(short glyph, uchar* ch, int* color); static COLORREF nhcolor_to_RGB(int c); -#endif HWND mswin_init_map_window () { static int run_once = 0; @@ -59,6 +66,196 @@ HWND mswin_init_map_window () { return ret; } +void mswin_map_stretch(HWND hWnd, LPSIZE lpsz, BOOL redraw) +{ + PNHMapWindow data; + RECT client_rt; + SCROLLINFO si; + SIZE wnd_size; + LOGFONT lgfnt; + + /* check arguments */ + if( !IsWindow(hWnd) || + !lpsz || + lpsz->cx<=0 || + lpsz->cy<=0 ) return; + + /* calculate window size */ + GetClientRect(hWnd, &client_rt); + wnd_size.cx = client_rt.right - client_rt.left; + wnd_size.cy = client_rt.bottom - client_rt.top; + + /* set new screen tile size */ + data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA); + data->xScrTile = ((data->mapMode==NHMAP_VIEW_FIT_TO_SCREEN)? wnd_size.cx : lpsz->cx) / COLNO; + data->yScrTile = ((data->mapMode==NHMAP_VIEW_FIT_TO_SCREEN)? wnd_size.cy : lpsz->cy) / ROWNO; + + /* set map origin point */ + data->map_orig.x = max(0, client_rt.left + (wnd_size.cx - data->xScrTile*COLNO)/2 ); + data->map_orig.y = max(0, client_rt.top + (wnd_size.cy - data->yScrTile*ROWNO)/2 ); + + data->map_orig.x -= data->map_orig.x % data->xScrTile; + data->map_orig.y -= data->map_orig.y % data->yScrTile; + + /* adjust horizontal scroll bar */ + if( data->mapMode==NHMAP_VIEW_FIT_TO_SCREEN ) + data->xPageSize = COLNO+1; /* disable scroll bar */ + else + data->xPageSize = wnd_size.cx/data->xScrTile; + if( wnd_size.cx/data->xScrTile >= COLNO ) { + data->xPos = 0; + GetNHApp()->bNoHScroll = TRUE; + } else { + GetNHApp()->bNoHScroll = FALSE; + data->xPos = max(0, min(COLNO, u.ux - data->xPageSize/2)); + } + + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMin = 0; + si.nMax = COLNO; + si.nPage = data->xPageSize; + si.nPos = data->xPos; + SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); + + /* adjust vertical scroll bar */ + if( data->mapMode==NHMAP_VIEW_FIT_TO_SCREEN ) + data->yPageSize = ROWNO+1; /* disable scroll bar */ + else + data->yPageSize = wnd_size.cy/data->yScrTile; + + if( wnd_size.cy/data->yScrTile >= ROWNO ) { + data->yPos = 0; + GetNHApp()->bNoVScroll = TRUE; + } else { + GetNHApp()->bNoVScroll = FALSE; + data->yPos = max(0, min(ROWNO, u.uy - data->yPageSize/2)); + } + + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMin = 0; + si.nMax = ROWNO; + si.nPage = data->yPageSize; + si.nPos = data->yPos; + SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + + /* create font */ + if( data->hMapFont ) DeleteObject(data->hMapFont); + ZeroMemory(&lgfnt, sizeof(lgfnt)); + lgfnt.lfHeight = -data->yScrTile; // height of font + lgfnt.lfWidth = -data->xScrTile; // average character width + lgfnt.lfEscapement = 0; // angle of escapement + lgfnt.lfOrientation = 0; // base-line orientation angle + lgfnt.lfWeight = FW_NORMAL; // font weight + lgfnt.lfItalic = FALSE; // italic attribute option + lgfnt.lfUnderline = FALSE; // underline attribute option + lgfnt.lfStrikeOut = FALSE; // strikeout attribute option + lgfnt.lfCharSet = OEM_CHARSET; // character set identifier + lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision + lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision + lgfnt.lfQuality = DEFAULT_QUALITY; // output quality + lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family + _tcscpy(lgfnt.lfFaceName, TEXT("Terminal")); + data->hMapFont = CreateFontIndirect(&lgfnt); + + mswin_cliparound(data->xCur, data->yCur); + + if(redraw) InvalidateRect(hWnd, NULL, TRUE); +} + +/* set map mode */ +int mswin_map_mode(HWND hWnd, int mode) +{ + PNHMapWindow data; + int oldMode; + SIZE mapSize; + + data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA); + if( mode == data->mapMode ) return mode; + + oldMode = data->mapMode; + data->mapMode = mode; + + switch( data->mapMode ) { + + case NHMAP_VIEW_ASCII4x6: + data->bAsciiMode = TRUE; + mapSize.cx = 4*COLNO; + mapSize.cy = 6*ROWNO; + break; + + case NHMAP_VIEW_ASCII6x8: + data->bAsciiMode = TRUE; + mapSize.cx = 6*COLNO; + mapSize.cy = 8*ROWNO; + break; + + case NHMAP_VIEW_ASCII8x8: + data->bAsciiMode = TRUE; + mapSize.cx = 8*COLNO; + mapSize.cy = 8*ROWNO; + break; + + case NHMAP_VIEW_ASCII16x8: + data->bAsciiMode = TRUE; + mapSize.cx = 16*COLNO; + mapSize.cy = 8*ROWNO; + break; + + case NHMAP_VIEW_ASCII7x12: + data->bAsciiMode = TRUE; + mapSize.cx = 7*COLNO; + mapSize.cy = 12*ROWNO; + break; + + case NHMAP_VIEW_ASCII8x12: + data->bAsciiMode = TRUE; + mapSize.cx = 8*COLNO; + mapSize.cy = 12*ROWNO; + break; + + case NHMAP_VIEW_ASCII16x12: + data->bAsciiMode = TRUE; + mapSize.cx = 16*COLNO; + mapSize.cy = 12*ROWNO; + break; + + case NHMAP_VIEW_ASCII12x16: + data->bAsciiMode = TRUE; + mapSize.cx = 12*COLNO; + mapSize.cy = 16*ROWNO; + break; + + case NHMAP_VIEW_ASCII10x18: + data->bAsciiMode = TRUE; + mapSize.cx = 10*COLNO; + mapSize.cy = 18*ROWNO; + break; + + case NHMAP_VIEW_FIT_TO_SCREEN: { + RECT client_rt; + GetClientRect(hWnd, &client_rt); + mapSize.cx = client_rt.right - client_rt.left; + mapSize.cy = client_rt.bottom - client_rt.top; + + data->bAsciiMode = TRUE; + } break; + + case NHMAP_VIEW_TILES: + default: + data->bAsciiMode = FALSE; + mapSize.cx = TILE_X*COLNO; + mapSize.cy = TILE_Y*ROWNO; + break; + } + + mswin_map_stretch(hWnd, &mapSize, TRUE); + + return oldMode; +} + +/* register window class for map window */ void register_map_window_class() { WNDCLASS wcex; @@ -81,7 +278,7 @@ void register_map_window_class() } } - +/* map window procedure */ LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PNHMapWindow data; @@ -116,60 +313,29 @@ LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara case WM_SIZE: { - SCROLLINFO si; - int xNewSize; - int yNewSize; - - xNewSize = LOWORD(lParam); - yNewSize = HIWORD(lParam); + SIZE size; - /* adjust horizontal scroll bar */ - if( xNewSize/TILE_X >= COLNO ) { - data->xPos = 0; - GetNHApp()->bNoHScroll = TRUE; + if( data->mapMode == NHMAP_VIEW_FIT_TO_SCREEN ) { + size.cx = LOWORD(lParam); + size.cy = HIWORD(lParam); } else { - GetNHApp()->bNoHScroll = FALSE; - data->xPos = max(0, min(COLNO, u.ux - xNewSize/TILE_X/2)); + /* mapping factor is unchaged we just need to adjust scroll bars */ + size.cx = data->xScrTile*COLNO; + size.cy = data->yScrTile*ROWNO; } - - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = 0; - si.nMax = COLNO; - si.nPage = xNewSize/TILE_X; - si.nPos = data->xPos; - SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); - - /* adjust vertical scroll bar */ - if( yNewSize/TILE_Y >= ROWNO ) { - data->yPos = 0; - GetNHApp()->bNoVScroll = TRUE; - } else { - GetNHApp()->bNoVScroll = FALSE; - data->yPos = max(0, min(ROWNO, u.uy - yNewSize/TILE_Y/2)); - } - - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = 0; - si.nMax = ROWNO; - si.nPage = yNewSize/TILE_Y; - si.nPos = data->yPos; - SetScrollInfo(hWnd, SB_VERT, &si, TRUE); - - /* erase window */ - InvalidateRect(hWnd, NULL, TRUE); + mswin_map_stretch(hWnd, &size, TRUE); } break; case WM_LBUTTONDOWN: NHEVENT_MS( - min(COLNO, data->xPos + LOWORD(lParam)/TILE_X), - min(ROWNO, data->yPos + HIWORD(lParam)/TILE_Y) + max(0, min(COLNO, data->xPos + (LOWORD(lParam)-data->map_orig.x)/data->xScrTile)), + max(0, min(ROWNO, data->yPos + (HIWORD(lParam)-data->map_orig.y)/data->yScrTile)) ); break; case WM_DESTROY: + if( data->hMapFont ) DeleteObject(data->hMapFont); free(data); SetWindowLong(hWnd, GWL_USERDATA, (LONG)0); break; @@ -180,6 +346,7 @@ LRESULT CALLBACK MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara return 0; } +/* on WM_COMMAND */ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { PNHMapWindow data; @@ -193,11 +360,7 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) data->map[msg_data->x][msg_data->y] = msg_data->glyph; /* invalidate the update area */ - rt.left = msg_data->x*TILE_X - TILE_X*data->xPos; - rt.top = msg_data->y*TILE_Y - TILE_Y*data->yPos; - rt.right = rt.left + TILE_X; - rt.bottom = rt.top + TILE_Y; - + nhcoord2display(data, msg_data->x, msg_data->y, &rt); InvalidateRect(hWnd, &rt, TRUE); } break; @@ -205,30 +368,17 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case MSNH_MSG_CLIPAROUND: { PMSNHMsgClipAround msg_data = (PMSNHMsgClipAround)lParam; - SCROLLINFO si; - int xPage, yPage; int x, y; - - /* get page size */ - if( !GetNHApp()->bNoHScroll ) { - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE; - GetScrollInfo(hWnd, SB_HORZ, &si); - xPage = si.nPage; - - x = max(0, min(COLNO, msg_data->x - xPage/2)); + /* get page size and center horizontally on x-position*/ + if( !GetNHApp()->bNoHScroll ) { + x = max(0, min(COLNO, msg_data->x - data->xPageSize/2)); SendMessage( hWnd, WM_HSCROLL, (WPARAM)MAKELONG(SB_THUMBTRACK, x), (LPARAM)NULL ); } + /* get page size and center vertically on y-position*/ if( !GetNHApp()->bNoVScroll ) { - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE; - GetScrollInfo(hWnd, SB_VERT, &si); - yPage = si.nPage; - - y = max(0, min(ROWNO, msg_data->y - yPage/2)); - + y = max(0, min(ROWNO, msg_data->y - data->yPageSize/2)); SendMessage( hWnd, WM_VSCROLL, (WPARAM)MAKELONG(SB_THUMBTRACK, y), (LPARAM)NULL ); } } @@ -252,25 +402,30 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) /* move focus rectangle at the cursor postion */ hdc = GetDC(hWnd); - rt.left = (data->xCur - data->xPos)*TILE_X; - rt.top = (data->yCur - data->yPos)*TILE_Y; - rt.right = rt.left + TILE_X; - rt.bottom = rt.top + TILE_Y; - DrawFocusRect(hdc, &rt); + + nhcoord2display(data, data->xCur, data->yCur, &rt); + if( data->bAsciiMode ) { + PatBlt(hdc, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, DSTINVERT); + } else { + DrawFocusRect(hdc, &rt); + } data->xCur = msg_data->x; data->yCur = msg_data->y; - rt.left = (data->xCur - data->xPos)*TILE_X; - rt.top = (data->yCur - data->yPos)*TILE_Y; - rt.right = rt.left + TILE_X; - rt.bottom = rt.top + TILE_Y; - DrawFocusRect(hdc, &rt); + + nhcoord2display(data, data->xCur, data->yCur, &rt); + if( data->bAsciiMode ) { + PatBlt(hdc, rt.left, rt.top, rt.right-rt.left, rt.bottom-rt.top, DSTINVERT); + } else { + DrawFocusRect(hdc, &rt); + } ReleaseDC(hWnd, hdc); } break; } } +/* on WM_CREATE */ void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) { PNHMapWindow data; @@ -285,9 +440,16 @@ void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) for(j=0; jmap[i][j] = -1; } + + data->bAsciiMode = FALSE; + + data->xScrTile = TILE_X; + data->yScrTile = TILE_Y; + SetWindowLong(hWnd, GWL_USERDATA, (LONG)data); } +/* on WM_PAINT */ void onPaint(HWND hWnd) { PNHMapWindow data; @@ -306,18 +468,20 @@ void onPaint(HWND hWnd) /* calculate paint rectangle */ if( !IsRectEmpty(&ps.rcPaint) ) { /* calculate paint rectangle */ - paint_rt.top = data->yPos + ps.rcPaint.top/TILE_X; - paint_rt.left = data->xPos + ps.rcPaint.left/TILE_Y; - paint_rt.bottom = min(data->yPos+ps.rcPaint.bottom/TILE_Y+1, ROWNO); - paint_rt.right = min(data->xPos+ps.rcPaint.right/TILE_X+1, COLNO); + paint_rt.left = max(data->xPos + (ps.rcPaint.left - data->map_orig.x)/data->xScrTile, 0); + paint_rt.top = max(data->yPos + (ps.rcPaint.top - data->map_orig.y)/data->yScrTile, 0); + paint_rt.right = min(data->xPos + (ps.rcPaint.right - data->map_orig.x)/data->xScrTile+1, COLNO); + paint_rt.bottom = min(data->yPos + (ps.rcPaint.bottom - data->map_orig.y)/data->yScrTile+1, ROWNO); + if( data->bAsciiMode #ifdef REINCARNATION - if (Is_rogue_level(&u.uz)) { + || Is_rogue_level(&u.uz) /* You enter a VERY primitive world! */ +#endif + ) { HGDIOBJ oldFont; - int offset; - oldFont = SelectObject(hDC, mswin_create_font(NHW_MAP, ATR_NONE, hDC)); + oldFont = SelectObject(hDC, data->hMapFont); SetBkMode(hDC, TRANSPARENT); /* draw the map */ @@ -327,74 +491,14 @@ void onPaint(HWND hWnd) uchar ch; TCHAR wch; RECT glyph_rect; - unsigned short g=data->map[i][j]; + int color; + + nhglyph2charcolor(data->map[i][j], &ch, &color); - /* (from wintty, naturally) - * - * Map the glyph back to a character. - * - * Warning: For speed, this makes an assumption on the order of - * offsets. The order is set in display.h. - */ - -#ifdef TEXTCOLOR - int color; - -#define zap_color(n) color = iflags.use_color ? zapcolors[n] : NO_COLOR -#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR -#define obj_color(n) color = iflags.use_color ? objects[n].oc_color : NO_COLOR -#define mon_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR -#define pet_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR -#define warn_color(n) color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR - -# else /* no text color */ - -#define zap_color(n) -#define cmap_color(n) -#define obj_color(n) -#define mon_color(n) -#define pet_color(c) -#define warn_color(c) - SetTextColor( hDC, nhcolor_to_RGB(CLR_WHITE) ); -#endif - - if ((offset = (g - GLYPH_WARNING_OFF)) >= 0) { /* a warning flash */ - ch = warnsyms[offset]; - warn_color(offset); - } else if ((offset = (g - GLYPH_SWALLOW_OFF)) >= 0) { /* swallow */ - /* see swallow_to_glyph() in display.c */ - ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)]; - mon_color(offset >> 3); - } else if ((offset = (g - GLYPH_ZAP_OFF)) >= 0) { /* zap beam */ - /* see zapdir_to_glyph() in display.c */ - ch = showsyms[S_vbeam + (offset & 0x3)]; - zap_color((offset >> 2)); - } else if ((offset = (g - GLYPH_CMAP_OFF)) >= 0) { /* cmap */ - ch = showsyms[offset]; - cmap_color(offset); - } else if ((offset = (g - GLYPH_OBJ_OFF)) >= 0) { /* object */ - ch = oc_syms[(int)objects[offset].oc_class]; - obj_color(offset); - } else if ((offset = (g - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ - ch = oc_syms[(int)objects[CORPSE].oc_class]; - mon_color(offset); - } else if ((offset = (g - GLYPH_PET_OFF)) >= 0) { /* a pet */ - ch = monsyms[(int)mons[offset].mlet]; - pet_color(offset); - } else { /* a monster */ - ch = monsyms[(int)mons[g].mlet]; - mon_color(g); - } - // end of wintty code - -#ifdef TEXTCOLOR if( color == NO_COLOR ) continue; else SetTextColor( hDC, nhcolor_to_RGB(color) ); -#endif - glyph_rect.left = (i-data->xPos)*TILE_X; - glyph_rect.top = (j-data->yPos)*TILE_Y; - glyph_rect.right = glyph_rect.left + TILE_X; - glyph_rect.bottom = glyph_rect.top + TILE_Y; + + nhcoord2display(data, i, j, &glyph_rect); DrawText(hDC, NH_A2W(&ch, &wch, 1), 1, @@ -402,10 +506,8 @@ void onPaint(HWND hWnd) DT_CENTER | DT_VCENTER | DT_NOPREFIX ); } - mswin_destroy_font( SelectObject(hDC, oldFont) ); - } else -#endif - { + SelectObject(hDC, oldFont); + } else { /* prepare tiles DC for mapping */ tileDC = CreateCompatibleDC(hDC); saveBmp = SelectObject(tileDC, GetNHApp()->bmpTiles); @@ -416,52 +518,67 @@ void onPaint(HWND hWnd) if(data->map[i][j]>0) { short ntile; int t_x, t_y; + RECT glyph_rect; ntile = glyph2tile[ data->map[i][j] ]; t_x = (ntile % TILES_PER_LINE)*TILE_X; t_y = (ntile / TILES_PER_LINE)*TILE_Y; - - BitBlt(hDC, (i-data->xPos)*TILE_X, (j-data->yPos)*TILE_Y, TILE_X, TILE_Y, tileDC, t_x, t_y, SRCCOPY ); + + nhcoord2display(data, i, j, &glyph_rect); + + StretchBlt( + hDC, + glyph_rect.left, + glyph_rect.top, + data->xScrTile, + data->yScrTile, + tileDC, + t_x, + t_y, + TILE_X, + TILE_Y, + SRCCOPY + ); } SelectObject(tileDC, saveBmp); DeleteDC(tileDC); } /* draw focus rect */ - paint_rt.left = (data->xCur - data->xPos)*TILE_X; - paint_rt.top = (data->yCur - data->yPos)*TILE_Y; - paint_rt.right = paint_rt.left + TILE_X; - paint_rt.bottom = paint_rt.top + TILE_Y; - DrawFocusRect(hDC, &paint_rt); + nhcoord2display(data, data->xCur, data->yCur, &paint_rt); + if( data->bAsciiMode ) { + PatBlt( hDC, + paint_rt.left, paint_rt.top, + paint_rt.right-paint_rt.left, paint_rt.bottom-paint_rt.top, + DSTINVERT ); + } else { + DrawFocusRect(hDC, &paint_rt); + } } EndPaint(hWnd, &ps); } +/* on WM_VSCROLL */ void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) { PNHMapWindow data; - SCROLLINFO si; + SCROLLINFO si; int yNewPos; int yDelta; /* get window data */ data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA); - - /* get page size */ - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE; - GetScrollInfo(hWnd, SB_VERT, &si); switch(LOWORD (wParam)) { /* User clicked shaft left of the scroll box. */ case SB_PAGEUP: - yNewPos = data->yPos-si.nPage; + yNewPos = data->yPos-data->yPageSize; break; /* User clicked shaft right of the scroll box. */ case SB_PAGEDOWN: - yNewPos = data->yPos+si.nPage; + yNewPos = data->yPos+data->yPageSize; break; /* User clicked the left arrow. */ @@ -484,13 +601,13 @@ void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) } yNewPos = max(0, yNewPos); - yNewPos = min(ROWNO, yNewPos); + yNewPos = min(ROWNO-data->yPageSize+1, yNewPos); if( yNewPos == data->yPos ) return; yDelta = yNewPos - data->yPos; data->yPos = yNewPos; - ScrollWindowEx (hWnd, 0, -TILE_Y * yDelta, + ScrollWindowEx (hWnd, 0, -data->yScrTile * yDelta, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE); @@ -500,31 +617,27 @@ void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) SetScrollInfo(hWnd, SB_VERT, &si, TRUE); } +/* on WM_HSCROLL */ void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) { PNHMapWindow data; - SCROLLINFO si; + SCROLLINFO si; int xNewPos; int xDelta; /* get window data */ data = (PNHMapWindow)GetWindowLong(hWnd, GWL_USERDATA); - /* get page size */ - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE; - GetScrollInfo(hWnd, SB_HORZ, &si); - switch(LOWORD (wParam)) { /* User clicked shaft left of the scroll box. */ case SB_PAGEUP: - xNewPos = data->xPos-si.nPage; + xNewPos = data->xPos-data->xPageSize; break; /* User clicked shaft right of the scroll box. */ case SB_PAGEDOWN: - xNewPos = data->xPos+si.nPage; + xNewPos = data->xPos+data->xPageSize; break; /* User clicked the left arrow. */ @@ -547,13 +660,13 @@ void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) } xNewPos = max(0, xNewPos); - xNewPos = min(COLNO, xNewPos); + xNewPos = min(COLNO-data->xPageSize+1, xNewPos); if( xNewPos == data->xPos ) return; xDelta = xNewPos - data->xPos; data->xPos = xNewPos; - ScrollWindowEx (hWnd, -TILE_X * xDelta, 0, + ScrollWindowEx (hWnd, -data->xScrTile * xDelta, 0, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE); @@ -564,8 +677,70 @@ void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); } +/* map nethack map coordinates to the screen location */ +void nhcoord2display(PNHMapWindow data, int x, int y, LPRECT lpOut) +{ + lpOut->left = (x - data->xPos)*data->xScrTile + data->map_orig.x; + lpOut->top = (y - data->yPos)*data->yScrTile + data->map_orig.y; + lpOut->right = lpOut->left + data->xScrTile; + lpOut->bottom = lpOut->top + data->yScrTile; +} + +/* map glyph to character/color combination */ +void nhglyph2charcolor(short g, uchar* ch, int* color) +{ + int offset; #ifdef TEXTCOLOR -static + +#define zap_color(n) *color = iflags.use_color ? zapcolors[n] : NO_COLOR +#define cmap_color(n) *color = iflags.use_color ? defsyms[n].color : NO_COLOR +#define obj_color(n) *color = iflags.use_color ? objects[n].oc_color : NO_COLOR +#define mon_color(n) *color = iflags.use_color ? mons[n].mcolor : NO_COLOR +#define pet_color(n) *color = iflags.use_color ? mons[n].mcolor : NO_COLOR +#define warn_color(n) *color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR + +# else /* no text color */ + +#define zap_color(n) +#define cmap_color(n) +#define obj_color(n) +#define mon_color(n) +#define pet_color(c) +#define warn_color(c) + *color = CLR_WHITE; +#endif + + if ((offset = (g - GLYPH_WARNING_OFF)) >= 0) { /* a warning flash */ + *ch = warnsyms[offset]; + warn_color(offset); + } else if ((offset = (g - GLYPH_SWALLOW_OFF)) >= 0) { /* swallow */ + /* see swallow_to_glyph() in display.c */ + *ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)]; + mon_color(offset >> 3); + } else if ((offset = (g - GLYPH_ZAP_OFF)) >= 0) { /* zap beam */ + /* see zapdir_to_glyph() in display.c */ + *ch = showsyms[S_vbeam + (offset & 0x3)]; + zap_color((offset >> 2)); + } else if ((offset = (g - GLYPH_CMAP_OFF)) >= 0) { /* cmap */ + *ch = showsyms[offset]; + cmap_color(offset); + } else if ((offset = (g - GLYPH_OBJ_OFF)) >= 0) { /* object */ + *ch = oc_syms[(int)objects[offset].oc_class]; + obj_color(offset); + } else if ((offset = (g - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ + *ch = oc_syms[(int)objects[CORPSE].oc_class]; + mon_color(offset); + } else if ((offset = (g - GLYPH_PET_OFF)) >= 0) { /* a pet */ + *ch = monsyms[(int)mons[offset].mlet]; + pet_color(offset); + } else { /* a monster */ + *ch = monsyms[(int)mons[g].mlet]; + mon_color(g); + } + // end of wintty code +} + +/* map nethack color to RGB */ COLORREF nhcolor_to_RGB(int c) { switch(c) { @@ -588,4 +763,3 @@ COLORREF nhcolor_to_RGB(int c) default: return RGB( 0, 0, 0); /* black */ } } -#endif diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index 537efe93c..72482ca27 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -8,6 +8,24 @@ #include "config.h" #include "global.h" + HWND mswin_init_map_window (); +void mswin_map_stretch(HWND hWnd, LPSIZE lpsz, BOOL redraw); + +#define NHMAP_VIEW_TILES 0 +#define NHMAP_VIEW_ASCII4x6 1 +#define NHMAP_VIEW_ASCII6x8 2 +#define NHMAP_VIEW_ASCII8x8 3 +#define NHMAP_VIEW_ASCII16x8 4 +#define NHMAP_VIEW_ASCII7x12 5 +#define NHMAP_VIEW_ASCII8x12 6 +#define NHMAP_VIEW_ASCII16x12 7 +#define NHMAP_VIEW_ASCII12x16 8 +#define NHMAP_VIEW_ASCII10x18 9 +#define NHMAP_VIEW_FIT_TO_SCREEN 10 + +int mswin_map_mode(HWND hWnd, int mode); + +#define ROGUE_LEVEL_MAP_MODE NHMAP_VIEW_ASCII12x16 #endif /* MSWINMapWindow_h */ diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index 21c754595..bf4607807 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -6,6 +6,7 @@ #include "mhmsg.h" #include "mhfont.h" +#define MSG_WRAP_TEXT #define MSG_VISIBLE_LINES 4 #define MAX_MSG_LINES 32 @@ -29,14 +30,17 @@ typedef struct mswin_nethack_message_window { int yPos; /* current vertical scrolling position */ int xMax; /* maximum horizontal scrolling position */ int yMax; /* maximum vertical scrolling position */ + int xPage; /* page size of horizontal scroll bar */ } NHMessageWindow, *PNHMessageWindow; static TCHAR szMessageWindowClass[] = TEXT("MSNHMessageWndClass"); -LRESULT CALLBACK MessageWndProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK NHMessageWndProc(HWND, UINT, WPARAM, LPARAM); static void register_message_window_class(); static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam); static void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam); +#ifndef MSG_WRAP_TEXT static void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam); +#endif static void onPaint(HWND hWnd); static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam); static HDC prepareDC( HDC hdc ); @@ -44,16 +48,23 @@ static HDC prepareDC( HDC hdc ); HWND mswin_init_message_window () { static int run_once = 0; HWND ret; + DWORD style; if( !run_once ) { register_message_window_class( ); run_once = 1; } - + +#ifdef MSG_WRAP_TEXT + style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL; +#else + style = WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL; +#endif + ret = CreateWindow( szMessageWindowClass, /* registered class name */ NULL, /* window name */ - WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL, /* window style */ + style, /* window style */ 0, /* horizontal position of window */ 0, /* vertical position of window */ 0, /* window width */ @@ -74,7 +85,7 @@ void register_message_window_class() ZeroMemory( &wcex, sizeof(wcex)); wcex.style = CS_NOCLOSE; - wcex.lpfnWndProc = (WNDPROC)MessageWndProc; + wcex.lpfnWndProc = (WNDPROC)NHMessageWndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = GetNHApp()->hApp; @@ -87,7 +98,7 @@ void register_message_window_class() RegisterClass(&wcex); } -LRESULT CALLBACK MessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT CALLBACK NHMessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -107,9 +118,11 @@ LRESULT CALLBACK MessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l SetFocus(GetNHApp()->hMainWnd); break; +#ifndef MSG_WRAP_TEXT case WM_HSCROLL: onMSNH_HScroll(hWnd, wParam, lParam); break; +#endif case WM_VSCROLL: onMSNH_VScroll(hWnd, wParam, lParam); @@ -135,27 +148,35 @@ LRESULT CALLBACK MessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l xNewSize = LOWORD(lParam); yNewSize = HIWORD(lParam); - data->xMax = max(0, (int)(1 + data->max_text - xNewSize/data->xChar)); - data->xPos = min(data->xPos, data->xMax); - - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = 0; - si.nMax = data->max_text; - si.nPage = xNewSize/data->xChar; - si.nPos = data->xPos; - SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); + if( xNewSize>0 || yNewSize>0 ) { + +#ifndef MSG_WRAP_TEXT + data->xPage = xNewSize/data->xChar; + data->xMax = max(0, (int)(1 + data->max_text - data->xPage)); + data->xPos = min(data->xPos, data->xMax); + + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMin = 0; + si.nMax = data->max_text; + si.nPage = data->xPage; + si.nPos = data->xPos; + SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); +#endif - data->yMax = MSG_LINES - MSG_VISIBLE_LINES + 1; - data->yPos = min(data->yPos, data->yMax); - - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = 0; - si.nMax = MSG_LINES; - si.nPage = MSG_VISIBLE_LINES; - si.nPos = data->yPos; - SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + data->yMax = MSG_LINES - MSG_VISIBLE_LINES - 1; + data->yPos = min(data->yPos, data->yMax); + + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMin = 0; + si.nMax = MSG_LINES; + si.nPage = MSG_VISIBLE_LINES; + si.nPos = data->yPos; + SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + } } break; @@ -175,45 +196,31 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) { PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam; SCROLLINFO si; - int i; + /* append text to the end of the array */ memmove(&data->window_text[0], &data->window_text[1], (MSG_LINES-1)*sizeof(data->window_text[0])); data->window_text[MSG_LINES-1].attr = msg_data->attr; strncpy(data->window_text[MSG_LINES-1].text, msg_data->text, MAXWINDOWTEXT); + /* reset V-scroll position to display new text */ data->yPos = data->yMax; + + ZeroMemory(&si, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = data->yPos; SetScrollInfo(hWnd, SB_VERT, &si, TRUE); - data->max_text = 0; - for( i=0; imax_text < strlen(data->window_text[i].text) ) - data->max_text = strlen(data->window_text[i].text); - - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE; - GetScrollInfo(hWnd, SB_HORZ, &si); - - data->xMax = max(0, (int)(1 + data->max_text - si.nPage) ); - data->xPos = min(data->xPos, data->xMax); - si.cbSize = sizeof(si); - si.fMask = SIF_POS | SIF_RANGE; - si.nMin = 0; - si.nMax = data->max_text; - si.nPos = data->xPos; - SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); - + /* update window content */ InvalidateRect(hWnd, NULL, TRUE); } break; case MSNH_MSG_CLEAR_WINDOW: { - // do nothing + InvalidateRect(hWnd, NULL, TRUE); break; } } @@ -228,6 +235,7 @@ void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) /* get window data */ data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); + ZeroMemory(&si, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_POS; GetScrollInfo(hWnd, SB_VERT, &si); @@ -283,6 +291,7 @@ void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) */ InvalidateRect(hWnd, NULL, TRUE); + ZeroMemory(&si, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = data->yPos; @@ -292,6 +301,7 @@ void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) } } +#ifndef MSG_WRAP_TEXT void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) { PNHMessageWindow data; @@ -301,6 +311,7 @@ void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) /* get window data */ data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); + ZeroMemory(&si, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_PAGE; GetScrollInfo(hWnd, SB_HORZ, &si); @@ -354,6 +365,8 @@ void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) ScrollWindowEx (hWnd, -data->xChar * xInc, 0, (CONST RECT *) NULL, (CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE); + + ZeroMemory(&si, sizeof(si)); si.cbSize = sizeof(si); si.fMask = SIF_POS; si.nPos = data->xPos; @@ -361,6 +374,7 @@ void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam) UpdateWindow (hWnd); } } +#endif // MSG_WRAP_TEXT void onPaint(HWND hWnd) { @@ -371,8 +385,8 @@ void onPaint(HWND hWnd) int FirstLine, LastLine; int i, x, y; HGDIOBJ oldFont; - char draw_buf[MAXWINDOWTEXT+2]; TCHAR wbuf[MAXWINDOWTEXT+2]; + size_t wlen; hdc = BeginPaint(hWnd, &ps); @@ -382,38 +396,63 @@ void onPaint(HWND hWnd) GetClientRect(hWnd, &client_rt); - FirstLine = max (0, data->yPos + ps.rcPaint.top/data->yChar - 1); - LastLine = min (MSG_LINES, data->yPos + ps.rcPaint.bottom/data->yChar); - for (i=FirstLine; ixChar * (-data->xPos); - - SetRect( &draw_rt, - client_rt.left, client_rt.bottom - data->yChar - 4, client_rt.right, client_rt.bottom ); - DrawEdge(hdc, &draw_rt, EDGE_SUNKEN, BF_TOP | BF_ADJUST); - DrawEdge(hdc, &draw_rt, EDGE_SUNKEN, BF_BOTTOM | BF_ADJUST); - - draw_rt.left = x; - draw_rt.right = client_rt.right - x; - - strcpy( draw_buf, "> " ); - strcat( draw_buf, data->window_text[i].text ); - } else { - y = client_rt.bottom - data->yChar * (LastLine - i) - 4; - x = data->xChar * (4 - data->xPos); - - SetRect( &draw_rt, - x, y, max(client_rt.right, client_rt.right-x), y+data->yChar ); - - strcpy( draw_buf, data->window_text[i].text ); - } - - if( strlen(draw_buf)>0 ) { - oldFont = SelectObject(hdc, mswin_create_font(NHW_MESSAGE, data->window_text[i].attr, hdc)); - DrawText(hdc, NH_A2W(draw_buf, wbuf, sizeof(wbuf)), strlen(draw_buf), &draw_rt, DT_VCENTER | DT_NOPREFIX); - mswin_destroy_font(SelectObject(hdc, oldFont)); + if( !IsRectEmpty(&ps.rcPaint) ) { + FirstLine = max (0, data->yPos + ps.rcPaint.top/data->yChar - 1); + LastLine = min (MSG_LINES-1, data->yPos + ps.rcPaint.bottom/data->yChar); + y = min( ps.rcPaint.bottom, client_rt.bottom - 2); + for (i=LastLine; i>=FirstLine; i--) { + if( i==MSG_LINES-1 ) { + x = data->xChar * (2 - data->xPos); + } else { + x = data->xChar * (4 - data->xPos); + } + + + if( strlen(data->window_text[i].text)>0 ) { + /* convert to UNICODE */ + NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf)); + wlen = _tcslen(wbuf); + + /* calculate text height */ + draw_rt.left = x; + draw_rt.right = client_rt.right; + draw_rt.top = y - data->yChar; + draw_rt.bottom = y; + + oldFont = SelectObject(hdc, mswin_create_font(NHW_MESSAGE, data->window_text[i].attr, hdc)); + +#ifdef MSG_WRAP_TEXT + DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT); + draw_rt.top = y - (draw_rt.bottom - draw_rt.top); + draw_rt.bottom = y; + DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK); +#else + DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX ); +#endif + mswin_destroy_font(SelectObject(hdc, oldFont)); + + y -= draw_rt.bottom - draw_rt.top; + } else { + y -= data->yChar; + } + + /* highligh the last line */ + if( i==MSG_LINES-1 ) { + draw_rt.left = client_rt.left; + draw_rt.right = draw_rt.left + 2*data->xChar; + DrawText(hdc, TEXT("> "), 2, &draw_rt, DT_NOPREFIX ); + + y -= 2; + draw_rt.left = client_rt.left; + draw_rt.right = client_rt.right; + draw_rt.top -= 2; + draw_rt.bottom = client_rt.bottom; + DrawEdge(hdc, &draw_rt, EDGE_SUNKEN, BF_TOP | BF_ADJUST); + DrawEdge(hdc, &draw_rt, EDGE_SUNKEN, BF_BOTTOM | BF_ADJUST); + } } } + EndPaint(hWnd, &ps); } @@ -433,13 +472,14 @@ void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam) /* Get the handle to the client area's device context. */ hdc = prepareDC( GetDC(hWnd) ); - saveFont = SelectObject(hdc, mswin_create_font(NHW_STATUS, ATR_NONE, hdc)); + saveFont = SelectObject(hdc, mswin_create_font(NHW_MESSAGE, ATR_NONE, hdc)); /* Extract font dimensions from the text metrics. */ GetTextMetrics (hdc, &tm); data->xChar = tm.tmAveCharWidth; data->xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * data->xChar/2; data->yChar = tm.tmHeight + tm.tmExternalLeading; + data->xPage = 1; /* Free the device context. */ mswin_destroy_font(SelectObject(hdc, saveFont)); @@ -456,7 +496,7 @@ HDC prepareDC( HDC hdc ) void mswin_message_window_size (HWND hWnd, LPSIZE sz) { PNHMessageWindow data; - RECT rt; + RECT rt, client_rt; GetWindowRect(hWnd, &rt); @@ -465,6 +505,10 @@ void mswin_message_window_size (HWND hWnd, LPSIZE sz) data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA); if(data) { - sz->cy = data->yChar * MSG_VISIBLE_LINES + 4; + /* set size to accomodate MSG_VISIBLE_LINES, highligh rectangle and + horizontal scroll bar (difference between window rect and client rect */ + GetClientRect(hWnd, &client_rt); + sz->cy = sz->cy-(client_rt.bottom - client_rt.top) + + data->yChar * MSG_VISIBLE_LINES + 4; } } \ No newline at end of file diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index abf259f9a..a09f98a65 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -271,6 +271,13 @@ void mswin_clear_nhwindow(winid wid) GetNHApp()->windowlist[wid].win, WM_MSNH_COMMAND, (WPARAM)MSNH_MSG_CLEAR_WINDOW, (LPARAM)NULL ); } + +#ifdef REINCARNATION + if( Is_rogue_level(&u.uz) ) + mswin_map_mode(mswin_hwnd_from_winid(WIN_MAP), ROGUE_LEVEL_MAP_MODE); + else + mswin_map_mode(mswin_hwnd_from_winid(WIN_MAP), GetNHApp()->mapDisplayMode); +#endif } /* -- Display the window on the screen. If there is data diff --git a/win/win32/resource.h b/win/win32/resource.h index def1994e6..48cca55b3 100644 --- a/win/win32/resource.h +++ b/win/win32/resource.h @@ -113,6 +113,17 @@ #define IDM_HELP_OPTIONS_LONG 32778 #define IDM_HELP_EXTCMD 32779 #define IDM_HELP_LICENSE 32780 +#define IDM_MAP_TILES 32781 +#define IDM_MAP_ASCII4X6 32782 +#define IDM_MAP_ASCII6X8 32783 +#define IDM_MAP_ASCII8X8 32784 +#define IDM_MAP_ASCII16X8 32785 +#define IDM_MAP_ASCII7X12 32786 +#define IDM_MAP_ASCII8X12 32787 +#define IDM_MAP_ASCII16X12 32788 +#define IDM_MAP_ASCII12X16 32789 +#define IDM_MAP_ASCII10X18 32790 +#define IDM_MAP_FIT_TO_SCREEN 32791 #define IDC_STATIC -1 // Next default values for new objects @@ -120,7 +131,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 143 -#define _APS_NEXT_COMMAND_VALUE 32781 +#define _APS_NEXT_COMMAND_VALUE 32793 #define _APS_NEXT_CONTROL_VALUE 1329 #define _APS_NEXT_SYMED_VALUE 110 #endif diff --git a/win/win32/winMS.h b/win/win32/winMS.h index ae88641f6..3b5e9cbfb 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -43,6 +43,9 @@ typedef struct mswin_nhwindow_app { boolean bNoHScroll; /* disable cliparound for horizontal grid (map) */ boolean bNoVScroll; /* disable cliparound for vertical grid (map) */ + + int mapDisplayMode; /* regular map display mode */ + int mapDisplayModeSave; /* saved map display mode */ } NHWinApp, *PNHWinApp; extern PNHWinApp GetNHApp(); diff --git a/win/win32/winhack.c b/win/win32/winhack.c index 372f159b6..afdf05a5a 100644 --- a/win/win32/winhack.c +++ b/win/win32/winhack.c @@ -8,6 +8,7 @@ #include "dlb.h" #include "resource.h" #include "mhmain.h" +#include "mhmap.h" #ifdef OVL0 #define SHARED_DCL @@ -52,6 +53,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, if( _nethack_app.bmpTiles==NULL ) panic("cannot load tiles bitmap"); _nethack_app.bNoHScroll = FALSE; _nethack_app.bNoVScroll = FALSE; + _nethack_app.mapDisplayMode = NHMAP_VIEW_TILES; // init controls LoadLibrary( TEXT("RICHED32.DLL") ); diff --git a/win/win32/winhack.rc b/win/win32/winhack.rc index 50638d155..9365bd974 100644 --- a/win/win32/winhack.rc +++ b/win/win32/winhack.rc @@ -46,6 +46,20 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Quit", IDM_EXIT END + POPUP "&Map" + BEGIN + MENUITEM "&0 - Use Tiles", IDM_MAP_TILES + MENUITEM "&1 - ASCII (4x6)", IDM_MAP_ASCII4X6 + MENUITEM "&2 - ASCII (6x8)", IDM_MAP_ASCII6X8 + MENUITEM "&3 - ASCII (8x8)", IDM_MAP_ASCII8X8 + MENUITEM "&4 - ASCII (16x8)", IDM_MAP_ASCII16X8 + MENUITEM "&5 - ASCII (7x12)", IDM_MAP_ASCII7X12 + MENUITEM "&6 - ASCII (8x12)", IDM_MAP_ASCII8X12 + MENUITEM "&7 - ASCII (16x12)", IDM_MAP_ASCII16X12 + MENUITEM "&8 - ASCII (12x16)", IDM_MAP_ASCII12X16 + MENUITEM "&9 - ASCII (10x18)", IDM_MAP_ASCII10X18 + MENUITEM "&Fit To Screen (ASCII only)", IDM_MAP_FIT_TO_SCREEN + END POPUP "&Help" BEGIN MENUITEM "&About ...", IDM_ABOUT