diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 1e4a86108f..b16037a5f8 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -27,6 +27,7 @@ - Fix: [#19924] Destructible cheat does not allow partial ride modification. - Fix: [#19950] Mine train block brake supports drawn incorrectly. - Fix: [#19987] [Plugin] ‘SetCheatAction’ has wrong ID in plugin API. +- Fix: [#19991] Crash using cut-away view. 0.4.4 (2023-03-28) ------------------------------------------------------------------------ diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 7b3f98345c..3b257b9545 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -1834,10 +1834,10 @@ InteractionInfo SetInteractionInfoFromPaintSession(PaintSession* session, uint32 { PROFILED_FUNCTION(); - PaintStruct* ps = &session->PaintHead; InteractionInfo info{}; - while ((ps = ps->NextQuadrantEntry) != nullptr) + PaintStruct* ps = session->PaintHead; + while (ps != nullptr) { PaintStruct* old_ps = ps; PaintStruct* next_ps = ps; @@ -1868,7 +1868,7 @@ InteractionInfo SetInteractionInfoFromPaintSession(PaintSession* session, uint32 } #pragma GCC diagnostic pop - ps = old_ps; + ps = old_ps->NextQuadrantEntry; } return info; } diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index e2c8519e02..0e2500a0cf 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -447,9 +447,9 @@ static PaintStruct* PaintArrangeStructsHelperRotation(PaintStruct* psQuadrantEnt // Iterates over all the quadrant lists and links them together as a // singly linked list. // The paint session has a head member which is the first entry. -static void PaintStructsLinkQuadrants(PaintSessionCore& session) +static void PaintStructsLinkQuadrants(PaintSessionCore& session, PaintStruct& psHead) { - PaintStruct* ps = &session.PaintHead; + PaintStruct* ps = &psHead; ps->NextQuadrantEntry = nullptr; uint32_t quadrantIndex = session.QuadrantBackIndex; @@ -477,15 +477,21 @@ template static void PaintSessionArrangeImpl(PaintSessionCore& se return; } - PaintStructsLinkQuadrants(session); + // psHead is an intermediate node that is used to link all the quadrant lists together, + // this was previously stored in PaintSession but only the NextQuadrantEntry is relevant here. + // The head node is not part of the linked list and just serves as an entry point. + PaintStruct psHead{}; + PaintStructsLinkQuadrants(session, psHead); PaintStruct* psNextQuadrant = PaintArrangeStructsHelperRotation( - &session.PaintHead, session.QuadrantBackIndex, PaintSortFlags::Neighbour); + &psHead, session.QuadrantBackIndex, PaintSortFlags::Neighbour); while (++quadrantIndex < session.QuadrantFrontIndex) { psNextQuadrant = PaintArrangeStructsHelperRotation(psNextQuadrant, quadrantIndex, PaintSortFlags::None); } + + session.PaintHead = psHead.NextQuadrantEntry; } using PaintArrangeWithRotation = void (*)(PaintSessionCore& session); @@ -552,13 +558,9 @@ void PaintDrawStructs(PaintSession& session) { PROFILED_FUNCTION(); - PaintStruct* ps = &session.PaintHead; - - for (ps = ps->NextQuadrantEntry; ps != nullptr;) + for (PaintStruct* ps = session.PaintHead; ps != nullptr; ps = ps->NextQuadrantEntry) { PaintDrawStruct(session, ps); - - ps = ps->NextQuadrantEntry; } } @@ -691,7 +693,7 @@ PaintSession* PaintSessionAlloc(DrawPixelInfo& dpi, uint32_t viewFlags) return GetContext()->GetPainter()->CreateSession(dpi, viewFlags); } -void PaintSessionFree([[maybe_unused]] PaintSession* session) +void PaintSessionFree(PaintSession* session) { GetContext()->GetPainter()->ReleaseSession(session); } diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index f1b049cac8..53c21fdc9b 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -179,7 +179,7 @@ public: struct PaintSessionCore { - PaintStruct PaintHead; + PaintStruct* PaintHead; PaintStruct* Quadrants[MaxPaintQuadrants]; PaintStruct* LastPS; PaintStringStruct* PSStringHead; diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp index 7d770c5bd1..989aa1591a 100644 --- a/src/openrct2/paint/Painter.cpp +++ b/src/openrct2/paint/Painter.cpp @@ -160,6 +160,7 @@ PaintSession* Painter::CreateSession(DrawPixelInfo& dpi, uint32_t viewFlags) session->Flags = 0; std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr); + session->PaintHead = nullptr; session->LastPS = nullptr; session->LastAttachedPS = nullptr; session->PSStringHead = nullptr;