NetHackW: fix focus flashing when using far look

Changed when we update the map window back buffer.  We now defer all
back buffer renderig until mswin_map_update is called.  We update
the window only within the main message loop thus we should only
get fully coherent map state rendered prior to getting input.
This commit is contained in:
Bart House
2021-01-23 11:44:35 -08:00
parent 093c53bead
commit d6b435a1d8
3 changed files with 51 additions and 38 deletions

View File

@@ -37,7 +37,8 @@ typedef struct mswin_nethack_map_window {
glyph_info map[COLNO][ROWNO];
glyph_info bkmap[COLNO][ROWNO];
boolean mapDirty[COLNO][ROWNO]; /* dirty flag for map */
boolean locDirty[COLNO][ROWNO]; /* dirty flag for map location */
boolean mapDirty; /* one or more map locations are dirty */
int mapMode; /* current map mode */
boolean bAsciiMode; /* switch ASCII/tiled mode */
boolean bFitToScreenMode; /* switch Fit map to screen mode on/off */
@@ -143,7 +144,7 @@ mswin_init_map_window()
}
void
mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
mswin_map_layout(HWND hWnd, LPSIZE map_size)
{
/* check arguments */
if (!IsWindow(hWnd) || !map_size || map_size->cx <= 0
@@ -370,10 +371,11 @@ mswin_map_stretch(HWND hWnd, LPSIZE map_size, BOOL redraw)
mswin_cliparound(data->xCur, data->yCur);
if (redraw) {
dirtyAll(data);
InvalidateRect(hWnd, NULL, TRUE);
}
// redraw all map locations
dirtyAll(data);
// invalidate entire map window
InvalidateRect(hWnd, NULL, TRUE);
}
/* set map mode */
@@ -481,13 +483,38 @@ mswin_map_mode(HWND hWnd, int mode)
mapSize.cx = data->tileWidth * COLNO;
mapSize.cy = data->tileHeight * ROWNO;
mswin_map_stretch(hWnd, &mapSize, TRUE);
mswin_map_layout(hWnd, &mapSize);
mswin_update_inventory(); /* for perm_invent to hide/show tiles */
return oldMode;
}
void mswin_map_update(HWND hWnd)
{
PNHMapWindow data = (PNHMapWindow)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (data->mapDirty)
{
/* update back buffer */
HBITMAP savedBitmap = SelectObject(data->tileDC, GetNHApp()->bmpMapTiles);
for (int i = 0; i < COLNO; i++)
for (int j = 0; j < ROWNO; j++)
if (data->locDirty[i][j])
{
paint(data, i, j);
RECT rect;
nhcoord2display(data, i, j, &rect);
InvalidateRect(data->hWnd, &rect, FALSE);
}
SelectObject(data->tileDC, savedBitmap);
data->mapDirty = FALSE;
}
}
/* register window class for map window */
void
register_map_window_class()
@@ -559,7 +586,7 @@ MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
size.cx = data->xFrontTile * COLNO;
size.cy = data->yFrontTile * ROWNO;
}
mswin_map_stretch(hWnd, &size, TRUE);
mswin_map_layout(hWnd, &size);
/* update window placement */
GetWindowRect(hWnd, &rt);
@@ -978,10 +1005,8 @@ static void setGlyph(PNHMapWindow data, int i, int j,
|| data->map[i][j].glyphflags != fg->glyphflags) {
data->map[i][j] = *fg;
data->bkmap[i][j] = *bg;
data->mapDirty[i][j] = TRUE;
RECT rect;
nhcoord2display(data, i, j, &rect);
InvalidateRect(data->hWnd, &rect, FALSE);
data->locDirty[i][j] = TRUE;
data->mapDirty = TRUE;
}
}
@@ -991,28 +1016,23 @@ static void clearAll(PNHMapWindow data)
for (int y = 0; y < ROWNO; y++) {
data->map[x][y] = nul_glyphinfo;
data->bkmap[x][y] = nul_glyphinfo;
data->mapDirty[x][y] = TRUE;
data->locDirty[x][y] = TRUE;
}
InvalidateRect(data->hWnd, NULL, FALSE);
data->mapDirty = TRUE;
}
static void dirtyAll(PNHMapWindow data)
{
for (int i = 0; i < COLNO; i++)
for (int j = 0; j < ROWNO; j++)
data->mapDirty[i][j] = TRUE;
InvalidateRect(data->hWnd, NULL, FALSE);
data->locDirty[i][j] = TRUE;
data->mapDirty = TRUE;
}
static void dirty(PNHMapWindow data, int x, int y)
{
data->mapDirty[x][y] = TRUE;
RECT rt;
nhcoord2display(data, x, y, &rt);
InvalidateRect(data->hWnd, &rt, FALSE);
data->locDirty[x][y] = TRUE;
data->mapDirty = TRUE;
}
static void
@@ -1031,7 +1051,7 @@ paint(PNHMapWindow data, int i, int j)
paintTile(data, i, j, &rect);
}
data->mapDirty[i][j] = FALSE;
data->locDirty[i][j] = FALSE;
}
@@ -1041,16 +1061,6 @@ onPaint(HWND hWnd)
{
PNHMapWindow data = (PNHMapWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);
/* update back buffer */
HBITMAP savedBitmap = SelectObject(data->tileDC, GetNHApp()->bmpMapTiles);
for (int i = 0; i < COLNO; i++)
for (int j = 0; j < ROWNO; j++)
if (data->mapDirty[i][j])
paint(data, i, j);
SelectObject(data->tileDC, savedBitmap);
PAINTSTRUCT ps;
HDC hFrontBufferDC = BeginPaint(hWnd, &ps);

View File

@@ -11,8 +11,9 @@
COLORREF nhcolor_to_RGB(int c);
HWND mswin_init_map_window(void);
void mswin_map_stretch(HWND hWnd, LPSIZE lpsz, BOOL redraw);
void mswin_map_layout(HWND hWnd, LPSIZE lpsz);
int mswin_map_mode(HWND hWnd, int mode);
void mswin_map_update(HWND hWnd);
#define ROGUE_LEVEL_MAP_MODE MAP_MODE_ASCII12x16
#define ROGUE_LEVEL_MAP_MODE_FIT_TO_SCREEN MAP_MODE_ASCII_FIT_TO_SCREEN

View File

@@ -2120,9 +2120,11 @@ mswin_putmsghistory(const char *msg, BOOLEAN_P restoring)
void
mswin_main_loop()
{
MSG msg;
while (!mswin_have_input()) {
MSG msg;
mswin_map_update(mswin_hwnd_from_winid(WIN_MAP));
if (!iflags.debug_fuzzer || PeekMessage(&msg, NULL, 0, 0, FALSE)) {
if(GetMessage(&msg, NULL, 0, 0) != 0) {
if (GetNHApp()->regNetHackMode
@@ -2214,7 +2216,7 @@ initMapTiles(void)
map_size.cx = GetNHApp()->mapTile_X * COLNO;
map_size.cy = GetNHApp()->mapTile_Y * ROWNO;
mswin_map_stretch(mswin_hwnd_from_winid(WIN_MAP), &map_size, TRUE);
mswin_map_layout(mswin_hwnd_from_winid(WIN_MAP), &map_size);
return TRUE;
}