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
+44 -34
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);