void buffer_fill_to_end(cell_t * buffer, cell_t * fill, int x, int y)
{
- ntassert(x >= 0 && x < console.width);
- ntassert(y >= 0 && ((y < console.height) || (y == console.height &&
+ nhassert(x >= 0 && x < console.width);
+ nhassert(y >= 0 && ((y < console.height) || (y == console.height &&
x == 0)));
cell_t * dst = buffer + console.width * y + x;
static void buffer_clear_to_end_of_line(cell_t * buffer, int x, int y)
{
- ntassert(x >= 0 && x < console.width);
- ntassert(y >= 0 && ((y < console.height) || (y == console.height &&
+ nhassert(x >= 0 && x < console.width);
+ nhassert(y >= 0 && ((y < console.height) || (y == console.height &&
x == 0)));
cell_t * dst = buffer + console.width * y + x;
cell_t *sentinel = buffer + console.width * (y + 1);
void buffer_write(cell_t * buffer, cell_t * cell, COORD pos)
{
- ntassert(pos.X >= 0 && pos.X < console.width);
- ntassert(pos.Y >= 0 && pos.Y < console.height);
+ nhassert(pos.X >= 0 && pos.X < console.width);
+ nhassert(pos.Y >= 0 && pos.Y < console.height);
cell_t * dst = buffer + (console.width * pos.Y) + pos.X;
*dst = *cell;
static void set_console_cursor(int x, int y)
{
- ntassert(x >= 0 && x < console.width);
- ntassert(y >= 0 && y < console.height);
+ nhassert(x >= 0 && x < console.width);
+ nhassert(y >= 0 && y < console.height);
console.cursor.X = max(0, min(console.width - 1, x));
console.cursor.Y = max(0, min(console.height - 1, y));
xputc_core(ch)
char ch;
{
- ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
- ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
+ nhassert(console.cursor.X >= 0 && console.cursor.X < console.width);
+ nhassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
boolean inverse = FALSE;
cell_t cell;
}
}
- ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
- ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
+ nhassert(console.cursor.X >= 0 && console.cursor.X < console.width);
+ nhassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
}
/*
void unload_keyboard_handler()
{
- ntassert(keyboard_handler.hLibrary != NULL);
+ nhassert(keyboard_handler.hLibrary != NULL);
FreeLibrary(keyboard_handler.hLibrary);
memset(&keyboard_handler, 0, sizeof(keyboard_handler_t));
L"Consolas");
success = SetConsoleOutputCP(437);
- ntassert(success);
+ nhassert(success);
success = SetCurrentConsoleFontEx(console.hConOut, FALSE, &console_font_info);
- ntassert(success);
+ nhassert(success);
}
/* restore_original_console_font will restore the console font and code page
char c = (char)i;
int count = MultiByteToWideChar(codePage, 0, &c, 1,
&console.cpMap[i], 1);
- ntassert(count == 1);
+ nhassert(count == 1);
}
}
if (console.hConOut == NULL)
return;
- ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
- ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
+ nhassert(console.cursor.X >= 0 && console.cursor.X < console.width);
+ nhassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
WORD attribute = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE;
DWORD unused;
s++;
}
- ntassert(console.cursor.X >= 0 && console.cursor.X < console.width);
- ntassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
+ nhassert(console.cursor.X >= 0 && console.cursor.X < console.width);
+ nhassert(console.cursor.Y >= 0 && console.cursor.Y < console.height);
SetConsoleCursorPosition(console.hConOut, console.cursor);
windowprocs.win_raw_print = early_raw_print;
console.hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
- ntassert(console.hConOut != NULL); // NOTE: this assert will not print
+ nhassert(console.hConOut != NULL); // NOTE: this assert will not print
GetConsoleScreenBufferInfo(console.hConOut, &console.origcsbi);
/* At this point early_raw_print will work */
console.hConIn = GetStdHandle(STD_INPUT_HANDLE);
- ntassert(console.hConIn != NULL);
+ nhassert(console.hConIn != NULL);
/* grow the size of the console buffer if it is not wide enough */
if (console.origcsbi.dwSize.X < console.width) {
/* NetHack may be freely redistributed. See license for details. */
#include "winos.h"
+#include "winMS.h"
+#include "win10.h"
+
#include "mhmap.h"
#include "mhfont.h"
#include "mhinput.h"
#include "mhmsg.h"
#include "resource.h"
-#include "winMS.h"
#include "color.h"
#include "patchlevel.h"
boolean bFitToScreenMode; /* switch Fit map to screen mode on/off */
int xPos, yPos; /* scroll position */
int xPageSize, yPageSize; /* scroll page size */
+ int xMin, xMax, yMin, yMax; /* scroll range */
int xCur, yCur; /* position of the cursor */
- int xScrTile, yScrTile; /* size of display tile */
+ int xScrTile, yScrTile; /* size of tile on screen in pixels */
POINT map_orig; /* map origin point */
- HFONT hMapFont; /* font for ASCII mode */
- boolean bUnicodeFont; /* font supports unicode page 437 */
+ HFONT hMapFont; /* font for ASCII mode */
+ boolean bUnicodeFont; /* font supports unicode page 437 */
+
+ int tileWidth; /* width of tile in pixels at 96 dpi */
+ int tileHeight; /* height of tile in pixels at 96 dpi */
+ double scale; /* scale factor */
+
} NHMapWindow, *PNHMapWindow;
static TCHAR szNHMapWindowClass[] = TEXT("MSNethackMapWndClass");
}
void
-mswin_map_stretch(HWND hWnd, LPSIZE lpsz, BOOL redraw)
+mswin_map_stretch(HWND hWnd, LPSIZE map_size, 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)
+ if (!IsWindow(hWnd) || !map_size || map_size->cx <= 0
+ || map_size->cy <= 0)
return;
+ PNHMapWindow data = (PNHMapWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
/* calculate window size */
+ RECT client_rt;
GetClientRect(hWnd, &client_rt);
+
+ SIZE wnd_size;
wnd_size.cx = client_rt.right - client_rt.left;
wnd_size.cy = client_rt.bottom - client_rt.top;
+ if (wnd_size.cx > 0 && wnd_size.cy > 0 && data->bFitToScreenMode) {
+ double windowAspectRatio =
+ (double) wnd_size.cx / (double) wnd_size.cy;
+ UINT mapWidth = COLNO * data->tileWidth;
+ UINT mapHeight = ROWNO * data->tileHeight;
+
+ double mapAspectRatio = (double) mapWidth / (double) mapHeight;
+
+ if (windowAspectRatio > mapAspectRatio)
+ data->scale = (double) wnd_size.cy / (double) mapHeight;
+ else
+ data->scale = (double) wnd_size.cx / (double) mapWidth;
+
+ } else {
+ // Auto size window
+
+ UINT windowDpi = 96;
+
+ if (gWin10.Valid) {
+ windowDpi = gWin10.GetDpiForWindow(hWnd);
+ if (windowDpi == 0)
+ windowDpi = 96;
+ }
+
+ windowDpi = max(96, windowDpi);
+ data->scale = (double) windowDpi / 96.0;
+ }
+
/* set new screen tile size */
- data = (PNHMapWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
- data->xScrTile =
- max(1, (data->bFitToScreenMode ? wnd_size.cx : lpsz->cx) / COLNO);
- data->yScrTile =
- max(1, (data->bFitToScreenMode ? wnd_size.cy : lpsz->cy) / ROWNO);
+ data->xScrTile = (int) (data->tileWidth * data->scale);
+ data->yScrTile = (int) (data->tileHeight * data->scale);
+
+ data->xScrTile = max(1, data->xScrTile);
+ data->yScrTile = max(1, data->yScrTile);
/* set map origin point */
data->map_orig.x =
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->bFitToScreenMode)
- data->xPageSize = COLNO + 1; /* disable scroll bar */
- else
- data->xPageSize = wnd_size.cx / data->xScrTile;
+ // Set horizontal scroll
- if (data->xPageSize >= COLNO) {
- data->xPos = 0;
- GetNHApp()->bNoHScroll = TRUE;
- } else {
- GetNHApp()->bNoHScroll = FALSE;
- data->xPos = max(
- 0, min(COLNO - data->xPageSize + 1, u.ux - data->xPageSize / 2));
- }
+ data->xPageSize = min(COLNO, wnd_size.cx / data->xScrTile);
+
+ GetNHApp()->bNoHScroll = (data->xPageSize == COLNO);
+
+ data->xMin = 0;
+ data->xMax = COLNO - data->xPageSize;
+ data->xPos = max(0, min(data->xMax, u.ux - (data->xPageSize / 2)));
+
+ SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
- si.nMin = 0;
- si.nMax = COLNO;
- si.nPage = data->xPageSize;
+ si.nMin = data->xMin;
+ si.nMax = data->xMax;
+ si.nPage = 1;
si.nPos = data->xPos;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
- /* adjust vertical scroll bar */
- if (data->bFitToScreenMode)
- data->yPageSize = ROWNO + 1; /* disable scroll bar */
- else
- data->yPageSize = wnd_size.cy / data->yScrTile;
+ data->yPageSize = min(ROWNO, wnd_size.cy / data->yScrTile);
- if (data->yPageSize >= ROWNO) {
- data->yPos = 0;
- GetNHApp()->bNoVScroll = TRUE;
- } else {
- GetNHApp()->bNoVScroll = FALSE;
- data->yPos = max(
- 0, min(ROWNO - data->yPageSize + 1, u.uy - data->yPageSize / 2));
- }
+ GetNHApp()->bNoVScroll = (data->yPageSize == ROWNO);
+
+ data->yMin = 0;
+ data->yMax = ROWNO - data->yPageSize;
+ data->yPos = max(0, min(data->yMax, 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.nMin = data->yMin;
+ si.nMax = data->yMax;
+ si.nPage = 1;
si.nPos = data->yPos;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
/* create font */
if (data->hMapFont)
DeleteObject(data->hMapFont);
+
+ LOGFONT lgfnt;
+
ZeroMemory(&lgfnt, sizeof(lgfnt));
lgfnt.lfHeight = -data->yScrTile; // height of font
lgfnt.lfWidth = -data->xScrTile; // average character width
case MAP_MODE_ASCII4x6:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 4 * COLNO;
- mapSize.cy = 6 * ROWNO;
+ data->tileWidth = 4;
+ data->tileHeight = 6;
break;
case MAP_MODE_ASCII6x8:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 6 * COLNO;
- mapSize.cy = 8 * ROWNO;
+ data->tileWidth = 6;
+ data->tileHeight = 8;
break;
case MAP_MODE_ASCII8x8:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 8 * COLNO;
- mapSize.cy = 8 * ROWNO;
+ data->tileWidth = 8;
+ data->tileHeight = 8;
break;
case MAP_MODE_ASCII16x8:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 16 * COLNO;
- mapSize.cy = 8 * ROWNO;
+ data->tileWidth = 16;
+ data->tileHeight = 8;
break;
case MAP_MODE_ASCII7x12:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 7 * COLNO;
- mapSize.cy = 12 * ROWNO;
+ data->tileWidth = 7;
+ data->tileHeight = 12;
break;
case MAP_MODE_ASCII8x12:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 8 * COLNO;
- mapSize.cy = 12 * ROWNO;
+ data->tileWidth = 8;
+ data->tileHeight = 12;
break;
case MAP_MODE_ASCII16x12:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 16 * COLNO;
- mapSize.cy = 12 * ROWNO;
+ data->tileWidth = 16;
+ data->tileHeight = 12;
break;
case MAP_MODE_ASCII12x16:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 12 * COLNO;
- mapSize.cy = 16 * ROWNO;
+ data->tileWidth = 12;
+ data->tileHeight = 16;
break;
case MAP_MODE_ASCII10x18:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = 10 * COLNO;
- mapSize.cy = 18 * ROWNO;
+ data->tileWidth = 10;
+ data->tileHeight = 18;
break;
- case MAP_MODE_ASCII_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;
-
+ case MAP_MODE_ASCII_FIT_TO_SCREEN:
data->bAsciiMode = TRUE;
data->bFitToScreenMode = TRUE;
- } break;
-
- case MAP_MODE_TILES_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->tileWidth = 12;
+ data->tileHeight = 16;
+ break;
+ case MAP_MODE_TILES_FIT_TO_SCREEN:
data->bAsciiMode = FALSE;
data->bFitToScreenMode = TRUE;
- } break;
+ data->tileWidth = GetNHApp()->mapTile_X;
+ data->tileHeight = GetNHApp()->mapTile_Y;
+ break;
case MAP_MODE_TILES:
default:
data->bAsciiMode = FALSE;
data->bFitToScreenMode = FALSE;
- mapSize.cx = GetNHApp()->mapTile_X * COLNO;
- mapSize.cy = GetNHApp()->mapTile_Y * ROWNO;
+ data->tileWidth = GetNHApp()->mapTile_X;
+ data->tileHeight = GetNHApp()->mapTile_Y;
break;
}
+ mapSize.cx = data->tileWidth * COLNO;
+ mapSize.cy = data->tileHeight * ROWNO;
+
mswin_map_stretch(hWnd, &mapSize, TRUE);
mswin_update_inventory(); /* for perm_invent to hide/show tiles */
data->xScrTile = GetNHApp()->mapTile_X;
data->yScrTile = GetNHApp()->mapTile_Y;
+ data->tileWidth = GetNHApp()->mapTile_X;
+ data->tileHeight = GetNHApp()->mapTile_Y;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) data);
}
if (data->bUnicodeFont) {
wch = winos_ascii_to_wide(ch);
DrawTextW(hDC, &wch, 1, &glyph_rect,
- DT_CENTER | DT_VCENTER | DT_NOPREFIX);
+ DT_CENTER | DT_VCENTER | DT_NOPREFIX);
} else {
DrawTextA(hDC, &ch, 1, &glyph_rect,
- DT_CENTER | DT_VCENTER | DT_NOPREFIX);
+ DT_CENTER | DT_VCENTER | DT_NOPREFIX);
}
SetTextColor(hDC, OldFg);
yNewPos = data->yPos;
}
- yNewPos = max(0, min(ROWNO - data->yPageSize + 1, yNewPos));
+ yNewPos = max(0, min(data->yMax, yNewPos));
if (yNewPos == data->yPos)
return;
xNewPos = data->xPos;
}
- xNewPos = max(0, min(COLNO - data->xPageSize + 1, xNewPos));
+ xNewPos = max(0, min(data->xMax, xNewPos));
if (xNewPos == data->xPos)
return;