From: Bart House Date: Sat, 23 Jan 2021 19:44:35 +0000 (-0800) Subject: NetHackW: fix focus flashing when using far look X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d6b435a1d825a423097496bf2faa0f9a4024000d;p=nethack 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. --- diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index ed3d4738c..aa79ef5a6 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -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); diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index 240d33bd3..679e16297 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -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 diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 31107659c..4e675671f 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -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; }