From a5cefd6c8b677b4764f05bf3085dc9121e638cbe Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Tue, 3 Jan 2023 21:10:20 +0300 Subject: [PATCH] Clear dirty rect during map updates Previous solution to replace squares was destructive in nature and could possibly lead to unexpected things (especially with mods where tile 0x293 might not be opaque black). New solution follows mapper refresh routines where entire dirty rect is reset to black as a preparation step. --- src/map.cc | 56 +++++++++++++++++++++++++---------------------------- src/tile.cc | 8 ++++++++ 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/map.cc b/src/map.cc index 5890d6a..5269ec7 100644 --- a/src/map.cc +++ b/src/map.cc @@ -1503,36 +1503,44 @@ static void isoWindowRefreshRect(Rect* rect) // 0x483EE4 static void isoWindowRefreshRectGame(Rect* rect) { - Rect clampedDirtyRect; - if (rectIntersection(rect, &gIsoWindowRect, &clampedDirtyRect) == -1) { + Rect rectToUpdate; + if (rectIntersection(rect, &gIsoWindowRect, &rectToUpdate) == -1) { return; } - tileRenderFloorsInRect(&clampedDirtyRect, gElevation); - _grid_render(&clampedDirtyRect, gElevation); - _obj_render_pre_roof(&clampedDirtyRect, gElevation); - tileRenderRoofsInRect(&clampedDirtyRect, gElevation); - _obj_render_post_roof(&clampedDirtyRect, gElevation); + // CE: Clear dirty rect to prevent most of the visual artifacts near map + // edges. + bufferFill(gIsoWindowBuffer + rectToUpdate.top * rectGetWidth(&gIsoWindowRect) + rectToUpdate.left, + rectGetWidth(&rectToUpdate), + rectGetHeight(&rectToUpdate), + rectGetWidth(&gIsoWindowRect), + 0); + + tileRenderFloorsInRect(&rectToUpdate, gElevation); + _obj_render_pre_roof(&rectToUpdate, gElevation); + tileRenderRoofsInRect(&rectToUpdate, gElevation); + _obj_render_post_roof(&rectToUpdate, gElevation); } // 0x483F44 static void isoWindowRefreshRectMapper(Rect* rect) { - Rect clampedDirtyRect; - if (rectIntersection(rect, &gIsoWindowRect, &clampedDirtyRect) == -1) { + Rect rectToUpdate; + if (rectIntersection(rect, &gIsoWindowRect, &rectToUpdate) == -1) { return; } - bufferFill(gIsoWindowBuffer + clampedDirtyRect.top * (_scr_size.right - _scr_size.left + 1) + clampedDirtyRect.left, - clampedDirtyRect.right - clampedDirtyRect.left + 1, - clampedDirtyRect.bottom - clampedDirtyRect.top + 1, - _scr_size.right - _scr_size.left + 1, + bufferFill(gIsoWindowBuffer + rectToUpdate.top * rectGetWidth(&gIsoWindowRect) + rectToUpdate.left, + rectGetWidth(&rectToUpdate), + rectGetHeight(&rectToUpdate), + rectGetWidth(&gIsoWindowRect), 0); - tileRenderFloorsInRect(&clampedDirtyRect, gElevation); - _grid_render(&clampedDirtyRect, gElevation); - _obj_render_pre_roof(&clampedDirtyRect, gElevation); - tileRenderRoofsInRect(&clampedDirtyRect, gElevation); - _obj_render_post_roof(&clampedDirtyRect, gElevation); + + tileRenderFloorsInRect(&rectToUpdate, gElevation); + _grid_render(&rectToUpdate, gElevation); + _obj_render_pre_roof(&rectToUpdate, gElevation); + tileRenderRoofsInRect(&rectToUpdate, gElevation); + _obj_render_post_roof(&rectToUpdate, gElevation); } // NOTE: Inlined. @@ -1721,18 +1729,6 @@ static int _square_load(File* stream, int flags) } } - // CE: Replace null tiles with a solid black tiles. This prevents copying - // buffer contents of nearby tiles during scrolling and repeating hex - // pointer when hovering mouse over null tiles. - for (int elevation = 0; elevation < ELEVATION_COUNT; elevation++) { - for (int tileIndex = 0; tileIndex < SQUARE_GRID_SIZE; tileIndex++) { - int tile = _square[elevation]->field_0[tileIndex]; - if (tile == 0x00010001) { - _square[elevation]->field_0[tileIndex] = 0x00010293; - } - } - } - return 0; } diff --git a/src/tile.cc b/src/tile.cc index 0eb5ebc..e781c7d 100644 --- a/src/tile.cc +++ b/src/tile.cc @@ -631,6 +631,14 @@ static void tileRefreshGame(Rect* rect, int elevation) return; } + // CE: Clear dirty rect to prevent most of the visual artifacts near map + // edges. + bufferFill(gTileWindowBuffer + rectToUpdate.top * gTileWindowPitch + rectToUpdate.left, + rectGetWidth(&rectToUpdate), + rectGetHeight(&rectToUpdate), + gTileWindowPitch, + 0); + tileRenderFloorsInRect(&rectToUpdate, elevation); _obj_render_pre_roof(&rectToUpdate, elevation); tileRenderRoofsInRect(&rectToUpdate, elevation);