diff --git a/distribution/changelog.txt b/distribution/changelog.txt index e400016fe3..41b9e92c80 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -8,6 +8,7 @@ - Change: [#24342] g2.dat is now split into g2.dat and fonts.dat. - Change: [#24362] The Windows installer now prevents installing to the same folder as RollerCoaster Tycoon 2 or Classic. - Change: [#24418] Small & Large Zero G Rolls can now be built on the LIM Launched RC without cheats if vehicle sprites are available. +- Fix: [#11071, #22958] The virtual floor does not always draw correctly. - Fix: [#24346] Possible crash during line drawing in OpenGL mode. - Fix: [#24353] ‘Show dirty visuals’ is off by one pixel and does not work correctly with higher framerates. - Fix: [#24362] When upgrading from an older version on Windows, old versions of official objects are not always removed. diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 39aa341cf8..daac21880b 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -1778,9 +1778,6 @@ namespace OpenRCT2::Ui::Windows } } - // Invalidate previous footpath piece. - VirtualFloorInvalidate(); - if (!isToolActive(WindowClass::Scenery)) { if (res.Error != GameActions::Status::Ok) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 3ded9964fa..469e9b88a5 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1075,13 +1075,11 @@ namespace OpenRCT2::Ui::Windows MouseUpDemolish(); break; case WIDX_NEXT_SECTION: - VirtualFloorInvalidate(); RideSelectNextSection(); if (!(gMapSelectFlags & MAP_SELECT_FLAG_ENABLE)) VirtualFloorSetHeight(_currentTrackBegin.z); break; case WIDX_PREVIOUS_SECTION: - VirtualFloorInvalidate(); RideSelectPreviousSection(); if (!(gMapSelectFlags & MAP_SELECT_FLAG_ENABLE)) VirtualFloorSetHeight(_currentTrackBegin.z); @@ -3197,9 +3195,6 @@ namespace OpenRCT2::Ui::Windows rideIndex, type, direction, liftHillAndAlternativeState, trackPos); WindowRideConstructionUpdateActiveElements(); - // Invalidate previous track piece (we may not be changing height!) - VirtualFloorInvalidate(); - if (!(gMapSelectFlags & MAP_SELECT_FLAG_ENABLE)) { // Set height to where the next track piece would begin @@ -3544,6 +3539,7 @@ namespace OpenRCT2::Ui::Windows *ride, entranceOrExitCoords, entranceOrExitCoords.direction, gRideEntranceExitPlaceType, stationNum); } WindowRideConstructionUpdateActiveElements(); + VirtualFloorSetHeight(entranceOrExitCoords.z); } } @@ -4788,9 +4784,6 @@ namespace OpenRCT2::Ui::Windows if (_currentTrackPitchEnd != TrackPitch::None) ViewportSetVisibility(ViewportVisibility::TrackHeights); - // Invalidate previous track piece (we may not be changing height!) - VirtualFloorInvalidate(); - if (!(gMapSelectFlags & MAP_SELECT_FLAG_ENABLE)) { // Set height to where the next track piece would begin diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index a917fa129f..7d62c65b9c 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -1767,11 +1767,6 @@ namespace OpenRCT2::Ui::Windows MapInvalidateSelectionRect(); MapInvalidateMapSelectionTiles(); - if (Config::Get().general.VirtualFloorStyle != VirtualFloorStyles::Off) - { - VirtualFloorInvalidate(); - } - gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT; diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp index 6f8b411249..df8772ae83 100644 --- a/src/openrct2/paint/Painter.cpp +++ b/src/openrct2/paint/Painter.cpp @@ -18,6 +18,7 @@ #include "../drawing/Text.h" #include "../localisation/Formatting.h" #include "../paint/Paint.h" +#include "../paint/VirtualFloor.h" #include "../profiling/Profiling.h" #include "../scenes/intro/IntroScene.h" #include "../ui/UiContext.h" @@ -46,6 +47,8 @@ void Painter::Paint(IDrawingEngine& de) } else { + VirtualFloorInvalidate(false); + de.PaintWindows(); UpdatePaletteEffects(); diff --git a/src/openrct2/paint/VirtualFloor.cpp b/src/openrct2/paint/VirtualFloor.cpp index 205cf2fa54..d3aafa703e 100644 --- a/src/openrct2/paint/VirtualFloor.cpp +++ b/src/openrct2/paint/VirtualFloor.cpp @@ -33,32 +33,19 @@ using namespace OpenRCT2; static constexpr uint16_t kVirtualFloorBaseSize = 5 * kCoordsXYStep; static constexpr CoordsXY kVirtualFloorBaseSizeXY = { kVirtualFloorBaseSize, kVirtualFloorBaseSize }; static uint16_t _virtualFloorHeight = 0; -static CoordsXYZ _virtualFloorLastMinPos; -static CoordsXYZ _virtualFloorLastMaxPos; -static uint32_t _virtualFloorFlags = 0; - -enum VirtualFloorFlags -{ - VIRTUAL_FLOOR_FLAG_NONE = 0, - VIRTUAL_FLOOR_FLAG_ENABLED = (1 << 1), - VIRTUAL_FLOOR_FORCE_INVALIDATION = (1 << 2), -}; +static CoordsXYZ _virtualFloorLastMinPos{ std::numeric_limits::max(), std::numeric_limits::max(), 0 }; +static CoordsXYZ _virtualFloorLastMaxPos{ std::numeric_limits::lowest(), std::numeric_limits::lowest(), 0 }; +static bool _virtualFloorIsEnabled = false; bool VirtualFloorIsEnabled() { - return (_virtualFloorFlags & VIRTUAL_FLOOR_FLAG_ENABLED) != 0; + return _virtualFloorIsEnabled; } -void VirtualFloorSetHeight(int16_t height) +void VirtualFloorSetHeight(const int16_t height) { - if (!VirtualFloorIsEnabled()) + if (VirtualFloorIsEnabled()) { - return; - } - - if (_virtualFloorHeight != height) - { - VirtualFloorInvalidate(); _virtualFloorHeight = height; } } @@ -80,7 +67,8 @@ void VirtualFloorEnable() } VirtualFloorReset(); - _virtualFloorFlags |= VIRTUAL_FLOOR_FLAG_ENABLED; + + _virtualFloorIsEnabled = true; } void VirtualFloorDisable() @@ -90,20 +78,22 @@ void VirtualFloorDisable() return; } - _virtualFloorFlags &= ~VIRTUAL_FLOOR_FLAG_ENABLED; - - // Force invalidation, even if the position hasn't changed. - _virtualFloorFlags |= VIRTUAL_FLOOR_FORCE_INVALIDATION; - VirtualFloorInvalidate(); - _virtualFloorFlags &= ~VIRTUAL_FLOOR_FORCE_INVALIDATION; + VirtualFloorInvalidate(true); VirtualFloorReset(); + + _virtualFloorIsEnabled = false; } -void VirtualFloorInvalidate() +void VirtualFloorInvalidate(const bool alwaysInvalidate) { PROFILED_FUNCTION(); + if (!VirtualFloorIsEnabled()) + { + return; + } + // First, let's figure out how big our selection is. CoordsXY min_position = { std::numeric_limits::max(), std::numeric_limits::max() }; CoordsXY max_position = { std::numeric_limits::lowest(), std::numeric_limits::lowest() }; @@ -125,11 +115,6 @@ void VirtualFloorInvalidate() } } - bool invalidateNewRegion - = (min_position.x != std::numeric_limits::max() && min_position.y != std::numeric_limits::max() - && max_position.x != std::numeric_limits::lowest() - && max_position.y != std::numeric_limits::lowest()); - // Apply the virtual floor size to the computed invalidation area. min_position.x -= kVirtualFloorBaseSize + 16; min_position.y -= kVirtualFloorBaseSize + 16; @@ -142,8 +127,7 @@ void VirtualFloorInvalidate() && _virtualFloorLastMaxPos.x != std::numeric_limits::lowest() && _virtualFloorLastMaxPos.y != std::numeric_limits::lowest()) { - if (_virtualFloorLastMinPos != min_position || _virtualFloorLastMaxPos != max_position - || (_virtualFloorFlags & VIRTUAL_FLOOR_FORCE_INVALIDATION) != 0) + if (_virtualFloorLastMinPos != min_position || _virtualFloorLastMaxPos != max_position || alwaysInvalidate) { LOG_VERBOSE( "Invalidating previous region, Min: %d %d, Max: %d %d", _virtualFloorLastMinPos.x, _virtualFloorLastMinPos.y, @@ -158,26 +142,18 @@ void VirtualFloorInvalidate() return; } - if (!(_virtualFloorFlags & VIRTUAL_FLOOR_FLAG_ENABLED)) - { - return; - } - LOG_VERBOSE("Min: %d %d, Max: %d %d", min_position.x, min_position.y, max_position.x, max_position.y); - if (invalidateNewRegion) - { - MapInvalidateRegion(min_position, max_position); + MapInvalidateRegion(min_position, max_position); - // Save minimal and maximal positions. - _virtualFloorLastMinPos.x = min_position.x; - _virtualFloorLastMinPos.y = min_position.y; - _virtualFloorLastMinPos.z = _virtualFloorHeight; + // Save minimal and maximal positions. + _virtualFloorLastMinPos.x = min_position.x; + _virtualFloorLastMinPos.y = min_position.y; + _virtualFloorLastMinPos.z = _virtualFloorHeight; - _virtualFloorLastMaxPos.x = max_position.x; - _virtualFloorLastMaxPos.y = max_position.y; - _virtualFloorLastMaxPos.z = _virtualFloorHeight; - } + _virtualFloorLastMaxPos.x = max_position.x; + _virtualFloorLastMaxPos.y = max_position.y; + _virtualFloorLastMaxPos.z = _virtualFloorHeight; } bool VirtualFloorTileIsFloor(const CoordsXY& loc) diff --git a/src/openrct2/paint/VirtualFloor.h b/src/openrct2/paint/VirtualFloor.h index 59d32c681b..91b97934c6 100644 --- a/src/openrct2/paint/VirtualFloor.h +++ b/src/openrct2/paint/VirtualFloor.h @@ -29,7 +29,7 @@ void VirtualFloorSetHeight(int16_t height); void VirtualFloorEnable(); void VirtualFloorDisable(); -void VirtualFloorInvalidate(); +void VirtualFloorInvalidate(const bool alwaysInvalidate); bool VirtualFloorTileIsFloor(const CoordsXY& loc);